연결된 계정

cURL, Python 및 Node 예제가 포함된 모든 연결된 계정 엔드포인트를 다룹니다: Google 및 Facebook 연결, 계정 목록 조회, 등록 정보 매칭 및 연결, 폴더, GMB 생성, 연결 해제.

연결된 계정은 Google Business Profile 또는 Facebook Pages 소유자가 부여한 OAuth 권한으로, API가 해당 계정에서 접근할 수 있는 등록 정보를 조회하고 관리할 수 있게 합니다. 이 리소스는 OAuth 링크 생성, 계정의 등록 정보와 사업장 간 매칭 또는 연결, 연결 해제라는 3가지 작업을 처리합니다. 목록 및 상세 정보를 조회하는 2개의 GET 요청에는 Read(읽기) 키를 사용할 수 있습니다. 모든 POST 요청에는 읽기 전용 등록 정보 조회를 포함하여 Write(쓰기) 키가 필요하며, 쓰기 요청에 Read 키를 사용하면 HTTP 400과 SY90016가 반환됩니다.

아래의 모든 예제는 첫 번째 예제에 나온 방식으로 클라이언트를 한 번 생성했다고 가정하며, 환경에서 LISTINGSAPI_KEY을 읽습니다. ID는 목록 엔드포인트에서 반환하는 connectedAccountId UUID와 base64 사업장 ID(TG9jYXRpb246MTgwMDI4OQ==)이며, 둘 다 절대로 URL 인코딩하지 않습니다.

엔드포인트 개요

메서드경로기능참조
POST/connected-accounts/connect-googleGoogle 계정용으로 24시간 동안 유효한 일괄 연결 링크를 생성합니다.Google 계정 연결
POST/connected-accounts/connect-facebookFacebook 계정용으로 24시간 동안 유효한 일괄 연결 링크를 생성합니다.Facebook 계정 연결
POST/locations/oauth_connect_url사업장 1개에 지정된 일회용 연결 링크를 생성합니다.사업장 1개용 OAuth 연결 URL
GET/connected-accounts연결된 계정의 목록을 연결 상태 및 연결된 항목 수와 함께 조회합니다.연결된 계정 목록 조회
GET/connected-accounts/{connectedAccountId}/details매칭 작업 상태를 포함하여 계정 1개의 정보를 조회합니다.연결된 계정의 상세 정보 조회
POST/connected-accounts/connected-account-listings계정에서 접근할 수 있는 게시 플랫폼의 등록 정보 목록을 조회합니다.연결된 계정의 등록 정보 조회
POST/connected-accounts/trigger-matches계정 1개 이상의 조회 및 매칭 작업을 대기열에 추가합니다.사업장 매칭 실행
GET/connected-accounts/{connectedAccountId}/connection-suggestions추천된 사업장과 등록 정보의 매칭 쌍을 조회합니다.연결 추천 목록 조회
POST/connected-accounts/confirm-matches추천을 수락하고 실제 연결을 생성합니다.연결 매칭 확정
POST/connected-accounts/connect-listing선택한 등록 정보 1개를 사업장 1개에 연결합니다.등록 정보를 사업장에 연결
POST/connected-accounts/disconnect-listing사업장 1개와 게시 플랫폼 1개 간의 연결을 해제합니다.등록 정보와 사업장 간의 연결 해제
POST/connected-accounts/create-location-from-listing게시 플랫폼의 등록 정보에서 새 사업장을 생성합니다.등록 정보에서 사업장 생성
GET/connected-accounts/{connectedAccountId}/foldersGoogle 계정 그룹(폴더) 목록을 조회합니다.GMB 폴더 목록 조회
POST/locations/create/gmb-listing사업장에 대해 완전히 새로운 Google Business Profile을 생성합니다.GMB 등록 정보 생성
POST/connected-accounts/disconnect-googleGoogle 계정 전체의 연결을 해제합니다.Google 계정 연결 해제
POST/connected-accounts/disconnect-facebookFacebook 계정 전체의 연결을 해제합니다.Facebook 계정 연결 해제
POST/locations/oauth-disconnect사업장 1개와 게시 플랫폼 간의 연결을 해제합니다(disconnect-listing과 동일한 작업).사업장 1개와 게시 플랫폼 간의 연결 해제

POST /connected-accounts/connect-google

유효 기간이 짧은 OAuth URL을 반환합니다. 계정 소유자를 이 URL로 리디렉션하면 Google이 소유자를 successUrl 또는 errorUrl로 다시 리디렉션합니다. 링크의 범위는 API 키를 소유한 계정으로 제한되므로 본문에는 리디렉션 URL 2개만 포함합니다. 부여된 권한이 만료된 계정의 링크를 다시 발급하면 연결을 중복 생성하지 않고 기존 연결을 갱신합니다.

이름전달 위치필수 여부참고 사항
inputbody예래퍼 객체이며, 전체 본문이 이 객체 아래에 들어갑니다.
input.successUrlbody예직접 관리하는 절대 https URL입니다. 동의 후 이 URL로 이동합니다.
input.errorUrlbody예직접 관리하는 절대 https URL입니다. 취소하거나 실패하면 이 URL로 이동합니다.
Connect Google
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"  }}'
JSON
{  "data": {    "bulkConnectLinkForGoogle": {      "success": true,      "url": "https://connect.example.com/oauth?token=8f3c1d92-...",      "errors": null    }  }}

위의 url은 자리표시자입니다. 실제 응답에서 반환된 url로 소유자를 이동시킵니다.

링크는 24시간 동안 유효합니다. errors은 생성에 실패한 경우에만 값이 채워지므로 url이 null이 아닌지 확인합니다. 래퍼 없이 구성한 본문이나 accountId이 포함된 본문은 HTTP 400으로 거부됩니다.

POST /connected-accounts/connect-facebook

Facebook용 엔드포인트이며 동일한 본문을 사용합니다. 이 과정에서 소유자는 Facebook 약관에 동의하고 API에 필요한 페이지 관리 권한을 부여하며, 권한을 하나라도 부여하지 않으면 연결을 통한 동기화가 불가능하므로 링크를 다시 발급하고 소유자가 다시 동의하도록 합니다.

이름전달 위치필수 여부참고 사항
inputbody예래퍼 객체입니다.
input.successUrlbody예직접 관리하는 절대 https URL입니다.
input.errorUrlbody예직접 관리하는 절대 https URL입니다.
Connect Facebook
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"  }}'
JSON
{  "data": {    "bulkConnectLinkForFacebook": {      "success": true,      "url": "https://connect.example.com/oauth?token=8f3c1d92-...",      "errors": null    }  }}

위의 url은 자리표시자입니다. 실제 응답에서 반환된 url로 소유자를 이동시킵니다.

응답 키는 bulkConnectLinkForFacebook이며, 그 외에는 Google 링크와 정확히 같은 방식으로 읽습니다. 소유자가 절차를 완료하면 목록 엔드포인트에 해당 계정이 FacebookAccount로 표시됩니다.

POST /locations/oauth_connect_url

소유자가 연결하려는 사업장을 이미 알고 있을 때 사용합니다. 링크는 지정한 사업장에 연결되므로 이후 매칭 단계가 없습니다. 소유자가 동의하면 자격 증명이 해당 사업장에 바로 연결됩니다. 위의 일괄 연결 링크 2개는 모두 사업장 대신 계정 전체를 연결합니다.

이름전달 위치필수 여부참고
inputbody예래퍼 객체입니다.
input.locationIdbody예Base64 사업장 ID 또는 원본 숫자 ID입니다.
input.sitebody예GOOGLE, FACEBOOK 또는 APPLE입니다.
input.successUrlbody예권한 부여 후 이동할 절대 URL입니다.
input.errorUrlbody예취소하거나 실패했을 때 이동할 절대 URL입니다.
Single-location link
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"  }}'
JSON
{  "data": {    "createConnectUrl": {      "success": true,      "url": "https://connect.example.com/oauth?token=8f3c1d92-...",      "errors": null    }  }}

위의 url은 자리표시자입니다. 실제 API 응답에서 반환된 url로 소유자를 안내합니다.

링크는 1회용이므로 캐시하지 말고 시도할 때마다 새로 생성합니다. 리디렉션 URL이 상대 URL이거나 파싱할 수 없는 경우 null url와 함께 success: true이 반환되므로, success뿐만 아니라 url도 확인합니다. 해당 사업장에 접근할 권한이 없는 키를 사용하면 SY90003와 함께 403이 반환됩니다. SDK는 site을 자동으로 대문자로 변환합니다.

연결된 계정 목록 조회

GET /connected-accounts

API 계정에 대해 접근 권한이 부여된 모든 계정을 각 계정의 연결 상태 및 연결된 사업장 수와 함께 반환합니다. 오프셋 기반 페이지이며, records[]과 pageInfo.totalRecords로 구성되고 중첩되지 않은 page 및 perPage 쿼리 매개변수로 페이지를 지정합니다. 정렬 순서는 계정 이메일의 오름차순으로 고정됩니다.

이름전달 위치필수 여부참고
pagequery아니요1부터 시작하는 페이지 번호입니다. 기본값은 1입니다.
perPagequery아니요페이지당 레코드 수입니다. 기본값은 20입니다.
publisherquery아니요GoogleAccount, FacebookAccount, AppleAccount, YelpAccount, TripadvisorAccount, LinkedinAccount, PinterestAccount 또는 TwitterAccount입니다.
statusquery아니요Connected, NotConnected 또는 ConnectionIssue입니다. 대문자와 소문자가 혼용됩니다.
List accounts
curl "https://listingsapi.com/api/v4/connected-accounts?publisher=GoogleAccount&status=Connected&page=1&perPage=20" \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "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"        }      ]    }  }}

email이 동의한 소유자에 해당하는 레코드를 선택하고 해당 레코드의 connectedAccountId을 저장합니다. 이후의 모든 호출에 이 값이 필요합니다. 4개의 쿼리 매개변수 이외의 항목은 거부되지 않고 무시되므로, JSON pageInfo을 전달하면 별도 알림 없이 페이지 1이 반환됩니다.

레코드의 status의미
CONNECTED자격 증명이 유효합니다. 매칭을 실행하거나 게시해도 됩니다.
MATCH_IN_PROGRESS매칭 작업이 대기 중이거나 실행 중입니다.
CONNECTIVITY_ISSUE부여된 권한이 만료되었습니다. connectivityIssue에 이유가 표시되며, 연결 링크를 다시 발급해야 합니다.

status 필터와 레코드의 status 필드에서 사용하는 값은 서로 다릅니다. CONNECTED을 필터에 다시 넣으면 유효하지 않은 enum 값이므로 400이 반환됩니다.

계정 1개의 세부 정보 조회

GET /connected-accounts/{connectedAccountId}/details

계정 1개를 대상으로 목록의 레코드 1개와 동일한 필드를 반환합니다. 매칭을 실행한 후 requestMatchesStatus을 폴링하거나, 해당 계정을 통해 업데이트를 전송하기 전에 status과 connectivityIssue를 확인할 때 사용합니다.

이름전달 위치필수 여부참고
connectedAccountIdpath예목록 엔드포인트에서 반환된 UUID입니다.
Account details
curl https://listingsapi.com/api/v4/connected-accounts/4f712c17-4f95-42dd-90f4-97171a2e67b5/details \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "data": {    "connectedAccountDetails": {      "details": {        "connectedAccountId": "4f712c17-4f95-42dd-90f4-97171a2e67b5",        "connectedAccountType": "GoogleAccount",        "status": "CONNECTED",        "connectivityIssue": null,        "connectedLocationsCount": 0,        "requestMatchesStatus": "MATCH_COMPLETED"      }    }  }}

레코드는 1단계 아래의 data.connectedAccountDetails.details에 있습니다. 추천 항목이 준비되면 requestMatchesStatus이 MATCH_IN_PROGRESS에서 MATCH_COMPLETED으로 변경됩니다. Completed는 매칭 처리가 끝났다는 뜻이며, 연결이 이루어졌다는 뜻은 아닙니다. 등록 정보를 확인하거나 연결할 때까지 connectedLocationsCount은 0로 유지됩니다.

계정이 접근할 수 있는 등록 정보 조회

POST /connected-accounts/connected-account-listings

사업장에 연결되어 있는지와 관계없이 해당 계정이 접근할 수 있는 모든 Google Business Profile 또는 Facebook 등록 정보를 나열합니다. 각 레코드의 id은 connect-listing과 create-location-from-listing에서 사용하는 connectedAccountListingId입니다. 읽기 작업만 수행하는 POST이며, records[]과 pageInfo로 구성된 오프셋 기반 페이지를 반환하고 본문에서 중첩되지 않은 page 및 perPage 키로 페이지를 지정합니다.

이름전달 위치필수 여부참고
connectedAccountIdbody예등록 정보를 조회할 계정의 UUID입니다. input으로 감싸지 않습니다.
pagebody아니요페이지 번호입니다. 기본값은 1입니다.
perPagebody아니요페이지당 레코드 수입니다. 기본값은 500이며 최댓값도 500입니다.
locationInfobody아니요이름, 주소, 지역, 우편번호, 매장 코드, 전화번호를 대상으로 하는 자유 텍스트 검색입니다.
Account listings
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" }'
JSON
{  "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        }      ]    }  }}

pageInfo.hasNextPage과 pageInfo.totalPages을 사용하여 결과를 페이지별로 조회합니다. SDK는 connectedAccountId을 자동으로 본문에 넣으므로, 이 사항은 직접 작성한 REST 호출에만 영향을 줍니다.

매칭 실행

POST /connected-accounts/trigger-matches

지정한 계정에서 접근할 수 있는 모든 프로필을 가져와 각각을 사업장 중 하나와 짝짓는 작업을 대기열에 추가합니다. 매칭 대상은 활성 상태이고 보관 처리되지 않았으며 아직 연결되지 않은 모든 사업장입니다. 제안만 기록하며, 확인하기 전에는 아무것도 연결하지 않습니다.

이름전달 위치필수 여부설명
inputbody예래퍼 객체입니다.
input.connectedAccountIdsbody예목록 엔드포인트에서 가져온 계정 UUID의 배열입니다.
Trigger matches
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"] } }'
JSON
{  "data": {    "connectedAccountsTriggerMatches": {      "success": true,      "failedIds": null    }  }}

success: true은 작업이 대기열에 추가되었다는 뜻이며, 매칭이 완료되었다는 뜻은 아닙니다. 대기열에 추가하지 못한 계정은 failedIds에 나열되며, success는 false입니다. 제안을 읽기 전에 requestMatchesStatus가 MATCH_COMPLETED가 될 때까지 상세 정보 엔드포인트를 폴링합니다. 반복 횟수에 상한을 두고 15초마다 폴링하면 Launch 요금제의 분당 요청 10회 제한을 지킬 수 있습니다.

연결 제안 조회

GET /connected-accounts/{connectedAccountId}/connection-suggestions

매칭 기능이 제안한 쌍을 반환합니다. 한쪽은 사업장(locationInfo이며, databaseId는 locationId입니다)이고 다른 쪽은 게시 플랫폼의 등록 정보(suggestedLocationInfo)입니다. 중첩되지 않은 page 및 perPage 쿼리 매개변수로 페이지를 지정하는 오프셋 기반 페이지이며, 정렬 순서는 사업장 정보의 오름차순으로 고정됩니다.

이름전달 위치필수 여부설명
connectedAccountIdpath예계정의 UUID입니다.
pagequery아니요1부터 시작하는 페이지 번호입니다. 기본값은 1입니다.
perPagequery아니요페이지당 레코드 수입니다. 기본값은 20입니다.
Suggestions
curl "https://listingsapi.com/api/v4/connected-accounts/4f712c17-4f95-42dd-90f4-97171a2e67b5/connection-suggestions?page=1&perPage=20" \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "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" } }        }      ]    }  }}

제안에는 id가 없습니다. confirm-matches에서 id를 만들려면 matchedDataDatabaseId와 accountType가 모두 필요하므로 함께 보관합니다. MATCH_COMPLETED 전에 너무 일찍 조회하면 엔드포인트가 totalRecords: 0와 함께 records: []를 반환하므로, "매칭 결과 없음"과 똑같이 보입니다.

accountType게시 플랫폼매칭 레코드 유형
GMBGoogle Business ProfileGmbLocationMatchedData
FBFacebook PagesFbLocationMatchedData
APPLEApple Business ConnectAppleLocationMatchedData

매칭 확인

POST /connected-accounts/confirm-matches

승인한 제안을 받아 실제 연결을 생성합니다. 각 id는 <MatchRecordType>:<matchedDataDatabaseId>를 base64로 인코딩한 값이며, 유형은 위 표에서 선택합니다. 계정은 레코드에서 추론하므로 connectedAccountId 필드는 없으며, input 안에 알 수 없는 필드가 있으면 400으로 요청을 거부합니다.

이름전달 위치필수 여부설명
inputbody예래퍼 객체입니다. matchRecordIds만 선언되어 있습니다.
input.matchRecordIdsbody예base64로 인코딩된 매칭 레코드 id의 배열입니다. 최소 1개가 필요합니다.
Confirm matches
# 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="] } }'
JSON
{  "data": {    "confirmConnectMatches": {      "success": true,      "failedIds": null    }  }}

failedIds에는 이미 처리된 레코드나 매칭 이후 보관 처리된 사업장처럼 확인할 수 없었던 항목의 디코딩된 matchedDataDatabaseId 값이 들어 있으므로, 이 값을 제안 레코드와 대조합니다. 전송하지 않은 제안은 그대로 유지됩니다. 확인하면 사업장이 등록 정보에 연결되며, 이 작업만으로 게시 플랫폼에 데이터가 전송되지는 않습니다.

등록 정보 1개를 사업장에 연결

POST /connected-accounts/connect-listing

제안이나 확인 단계 없이 이미 선택한 등록 정보 1개를 사업장 1개에 연결합니다. 예를 들어 이름이 비슷한 매장 2곳이 가까이 있어 매칭이 모호하고 운영자가 계정의 등록 정보 중에서 올바른 항목을 선택하는 경우에 사용합니다.

이름전달 위치필수 여부설명
inputbody예래퍼 객체입니다.
input.locationIdbody예base64로 인코딩된 사업장 id입니다.
input.connectedAccountIdbody예등록 정보를 소유한 계정의 UUID입니다.
input.connectedAccountListingIdbody예계정 등록 정보 엔드포인트에서 가져온 레코드의 id입니다. listingId가 아닙니다.
Connect listing
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=="  }}'
JSON
{  "data": {    "connectListing": {      "success": true,      "message": null    }  }}

연결에 실패하면 null이 아닌 message와 함께 success: false를 반환하며, 예를 들어 등록 정보 id에 해당하는 항목을 찾을 수 없으면 Listing record not found를 반환하고, 등록 정보가 이미 다른 사업장에 연결되어 있으면 이를 알리는 메시지를 반환합니다. 두 SDK 모두에서 이 메서드는 연결된 계정 리소스가 아닌 등록 정보 리소스에 있습니다.

사업장에서 등록 정보 1개 연결 해제

POST /connected-accounts/disconnect-listing

사업장 1개와 게시 플랫폼 1개 사이의 연결을 끊습니다. 사업장과 해당 데이터는 유지되며, 해당 게시 플랫폼으로 보내는 동기화만 중지됩니다. 일괄 처리 엔드포인트가 아니므로 사업장별로 반복 호출합니다. 매장을 다른 Google 계정에 연결하려면 먼저 여기서 연결을 해제한 다음 새 계정에서 매칭하거나 연결합니다.

이름전달 위치필수 여부설명
inputbody예래퍼 객체입니다.
input.locationIdbody예사업장 1개의 base64로 인코딩된 id입니다.
input.sitebody둘 중 하나GOOGLE, FACEBOOK 또는 APPLE입니다. providerId를 전송하지 않으면 필수입니다.
input.providerIdbody둘 중 하나site 대신 사용하는 게시 플랫폼 자체의 계정 식별자입니다.
Disconnect listing
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" } }'
JSON
{  "data": {    "disconnectConnectedAccountsLocations": {      "clientMutationId": null,      "success": true,      "errors": null    }  }}

site와 providerId를 모두 전송하지 않으면 SY10056를 반환합니다. 해당 사이트에 활성 연결이 없는 사업장의 경우 아무 알림 없이 성공을 반환하지 않고 SY10057를 반환하므로, success: true는 실제로 연결이 제거되었음을 의미합니다. SDK는 site만 받으며, 이를 대문자로 변환합니다.

등록 정보에서 사업장 생성

POST /connected-accounts/create-location-from-listing

매칭은 등록 정보를 이미 보유한 사업장과 연결하기만 합니다. 사업장이 없는 등록 정보의 경우, 이 작업은 게시 플랫폼의 데이터로 사업장을 생성하고 해당 등록 정보에 즉시 연결합니다. Google에서는 이름, 주소, 좌표, 전화번호, 웹사이트, 설명, 정규 및 특별 영업시간, 카테고리, 개업일, 매장 코드, 시간대와 함께 등록 정보의 Google 속성에서 추출한 결제 수단과 소셜 링크를 가져옵니다. Facebook에서는 이름, 사업장, 영업시간, 카테고리, 설명, 연락처 정보를 가져옵니다.

Google에서 가져오는 경우 데이터가 Google에 다시 제출되지 않으므로, 첫 번째 사업장 업데이트가 해당 등록 정보에 게시될 때까지 등록 정보는 IN_PROGRESS 상태로 유지됩니다. 다른 모든 게시 플랫폼에는 정상적으로 제출되며, 이 엔드포인트는 사이트 범위를 받지 않으므로 계정의 전체 게시 플랫폼을 대상으로 사업장을 생성합니다. 생성 직후 enabledSiteIds로 범위를 좁히고 해당 업데이트를 즉시 전송해야 합니다. 생성 후 곧 다른 게시 플랫폼의 주문 항목이 생성되며, 이미 생성된 항목은 이 업데이트로 철회되지 않습니다.

두 SDK 모두 아직 이 엔드포인트를 래핑하지 않으므로, Python 및 Node 예제는 동일한 헤더를 사용하여 REST를 호출합니다.

이름전달 위치필수 여부참고 사항
inputbody예래퍼 객체입니다.
input.connectedAccountIdbody예등록 정보를 소유한 계정의 UUID입니다.
input.connectedAccountListingIdbody예계정 등록 정보 엔드포인트에서 반환된 레코드의 id입니다. listingId이 아닙니다.
Create from listing
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=="  }}'
JSON
{  "data": {    "createLocationFromConnectedAccountListing": {      "success": true,      "locationId": 88277,      "errors": null    }  }}

locationId은 새 사업장의 databaseId 값 자체입니다. 실패 시 success는 false이고, locationId는 null이며, errors에는 SY81067(등록 정보 id에 해당하는 항목을 찾지 못함)과 같은 사유 코드가 포함됩니다. 다른 원인으로는 이미 다른 사업장에 연결된 등록 정보 또는 자격 증명이 만료된 계정이 있습니다. 생성 후에는 다른 사업장과 동일하게 관리합니다.

Google 계정의 폴더 목록 조회

GET /connected-accounts/{connectedAccountId}/folders

연결된 Google 계정이 액세스할 수 있는 Google Business Profile 계정 그룹(폴더)을 반환합니다. 새 프로필이 소유자가 의도한 그룹에 생성되도록 GMB 등록 정보를 생성하기 전에 사용합니다. 응답은 페이지가 아니라 getFoldersUnderGoogleAccount 아래의 일반 배열입니다. 이 경로는 GoogleAccount 연결에만 유효합니다.

이름전달 위치필수 여부참고 사항
connectedAccountIdpath예Google 유형 계정의 UUID입니다.
Folders
curl https://listingsapi.com/api/v4/connected-accounts/4f712c17-4f95-42dd-90f4-97171a2e67b5/folders \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "data": {    "getFoldersUnderGoogleAccount": [      { "folderId": "accounts/104890024806530350198", "folderName": "Bright Smile Dental", "locationCount": null }    ]  }}

folderId은 숫자가 아니라 accounts/{id} 문자열이므로 그대로 사용합니다. Google이 locationCount를 제공하지 않으면 값이 null일 수 있으므로 선택 사항으로 취급합니다.

사업장의 Google Business Profile 생성

POST /locations/create/gmb-listing

Google 등록 정보가 없는 사업장에 대해 연결된 Google 계정 아래에 새 Google 등록 정보를 생성하며, 선택적으로 폴더 안에 생성할 수 있습니다. 기존 등록 정보를 연결하는 connect-listing과는 다릅니다. 사업장에는 이름, 주소, 전화번호가 이미 있어야 하며, 사업장마다 Google 등록 정보는 1개만 존재할 수 있습니다.

이름전달 위치필수 여부참고 사항
inputbody예래퍼 객체입니다.
input.locationIdbody예Base64 사업장 id입니다.
input.connectedAccountIdbody예등록 정보를 생성할 Google 계정의 UUID입니다.
input.folderIdbody아니요폴더 엔드포인트에서 반환된 accounts/{id} 문자열입니다. 계정 루트에 생성하려면 생략합니다.
Create GMB listing
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"  }}'
JSON
{  "data": {    "createGmbListingForLocation": {      "clientMutationId": null,      "success": true,      "errors": null    }  }}

생성은 비동기로 이루어집니다. success: true은 요청이 수락되었음을 의미하며, Google은 새 프로필을 게시하기 전에 검토합니다. success이 false이면 errors에 필수 필드 누락, 기존 Google 등록 정보 존재, 보관 처리된 사업장 또는 비활성 계정과 같은 이유가 표시됩니다.

Google 계정 전체 연결 해제

POST /connected-accounts/disconnect-google

계정 전체의 연결을 해제합니다. 이 계정을 통해 연결된 모든 사업장의 동기화가 중지됩니다. locationIds 필드는 없으며, 계정은 유지하면서 사업장 하나의 연결만 해제하려면 disconnect-listing을 사용합니다. 고객이 서비스를 떠나거나, 문제가 있는 권한 부여를 해제할 수 없어 새 연결 링크로 다시 시작하려는 경우에 사용합니다.

이름위치필수 여부참고
inputbody예래퍼 객체입니다.
input.connectedAccountIdbody예Google 계정의 UUID입니다. 계정 전체의 연결이 해제됩니다.
Disconnect Google
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" } }'
JSON
{  "data": {    "gmbBulkDisconnect": {      "success": true    }  }}

알 수 없는 connectedAccountId에도 success: true이 반환되므로, 이는 "요청이 처리되었다"는 의미이며 "활성 연결이 제거되었다"는 의미는 아닙니다. 확실히 확인해야 한다면 연결된 계정 목록을 다시 조회합니다.

Facebook 계정 전체 연결 해제

POST /connected-accounts/disconnect-facebook

동일한 본문을 사용하는 Facebook용 작업입니다. 이 계정을 통해 연결된 페이지의 동기화가 중지되고 Facebook 상호작용이 더 이상 표시되지 않습니다.

이름위치필수 여부참고
inputbody예래퍼 객체입니다.
input.connectedAccountIdbody예Facebook 계정의 UUID입니다. 계정 전체의 연결이 해제됩니다.
Disconnect Facebook
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" } }'
JSON
{  "data": {    "fbBulkDisconnect": {      "success": true    }  }}

응답 키는 fbBulkDisconnect입니다. Google과 마찬가지로 알 수 없는 id에 대한 success: true은 제거가 아니라 처리를 의미합니다.

게시 플랫폼에서 사업장 하나의 연결 해제

POST /locations/oauth-disconnect

사업장별 OAuth 흐름에서 연결 해제를 담당합니다. 별도 경로로 제공되는 disconnect-listing과 동일한 작업이며, input 본문과 disconnectConnectedAccountsLocations 응답 키도 동일합니다. 연동 코드에서 더 이해하기 쉬운 경로를 선택합니다.

이름위치필수 여부참고
inputbody예래퍼 객체입니다.
input.locationIdbody예해당 사업장 하나의 Base64 id입니다.
input.sitebody둘 중 하나GOOGLE, FACEBOOK 또는 APPLE입니다. providerId을 보내지 않으면 필수입니다.
input.providerIdbody둘 중 하나site 대신 사용하는 게시 플랫폼 자체의 계정 식별자입니다.
OAuth disconnect
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" } }'
JSON
{  "data": {    "disconnectConnectedAccountsLocations": {      "clientMutationId": null,      "success": true,      "errors": null    }  }}

동일한 SY10056 및 SY10057 규칙이 적용되며, 이 사업장에 작업을 수행할 권한이 없는 키를 사용하면 SY90003과 함께 403이 반환됩니다. 연결을 해제해도 사업장과 해당 데이터는 그대로 유지되며, 해당 게시 플랫폼으로 보내는 동기화만 중지됩니다. 이후 올바른 등록 정보를 연결하려면 소유자가 연결 URL을 통해 다시 진행하도록 하거나, 매칭과 connect-listing을 실행합니다.

발생할 수 있는 오류

잘못된 형식의 요청이나 유효하지 않은 키에는 최상위 errors[]이 포함된 4xx가 반환되며, 해당 객체의 message은 코드로 시작합니다. 쓰기 요청에는 success: false과 data.<operation> 내부의 사유가 포함된 200이 반환될 수도 있으므로, 모든 쓰기 요청의 응답 본문을 확인합니다. 전체 목록은 오류 코드에서 확인할 수 있습니다.

코드 또는 상태의미해결 방법
SY90016 (400)POST에 Read 키가 사용되었습니다.Write 키를 사용합니다.
SY90003 (403)이 키에는 이 사업장을 연결하거나 연결 해제할 권한이 없습니다.해당 사업장에 접근할 수 있는 키를 사용합니다.
SY10056 (200)연결 해제 요청에 site과 providerId이 모두 전달되지 않았습니다.둘 중 하나를 보냅니다.
SY10057 (200)이 사업장에는 해당 사이트에 대한 활성 연결이 없습니다.제거할 연결이 없으므로 사업장의 등록 정보를 확인합니다.
SY81067 (200)create-from-listing에서 connectedAccountListingId에 해당하는 항목을 찾지 못했습니다.계정의 등록 정보를 다시 조회하고 레코드의 id을 사용합니다.
400, Variable "$input" ... was not provided본문이 input으로 감싸져 있지 않거나 필수 필드가 누락되었습니다.본문을 input 아래에 중첩하고, listingId이 아닌 connectedAccountListingId을 사용합니다.
400, 유효하지 않은 enum레코드의 CONNECTED 상태가 목록 조회의 status 필터에 다시 입력되었습니다.Connected, NotConnected 또는 ConnectionIssue로 필터링합니다.
429요청 속도 제한을 초과했습니다.Retry-After만큼 기다립니다. 요청 속도 제한을 참고합니다.

다음 단계