Fetch Google, Facebook and Bing profile analytics

Pull daily Google and Facebook profile metrics and weekly Bing views for a location, total a series for the month, and compare two periods.

Profile analytics tell you how often a location was seen and acted on at each publisher: impressions, direction requests, calls and website clicks. Every metric is a time series of { startTime, value } points, so the totals you show are ones you compute.

1. Read Google metrics for a date range

GET /locations/{locationId}/google-analytics?fromDate=&toDate= returns data.googleInsights with one daily series per metric. total is profile impressions, search plus maps; it does not include the action metrics.

Google
curl "https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/google-analytics?fromDate=2026-08-01&toDate=2026-08-31" \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "data": {    "googleInsights": {      "total": [        { "startTime": "2026-08-01T00:00:00+00:00", "value": 412 },        { "startTime": "2026-08-02T00:00:00+00:00", "value": 388 }      ],      "search": [{ "startTime": "2026-08-01T00:00:00+00:00", "value": 300 }],      "maps": [{ "startTime": "2026-08-01T00:00:00+00:00", "value": 112 }],      "directionsAction": [{ "startTime": "2026-08-01T00:00:00+00:00", "value": 24 }],      "phoneAction": [{ "startTime": "2026-08-01T00:00:00+00:00", "value": 8 }],      "websiteAction": [{ "startTime": "2026-08-01T00:00:00+00:00", "value": 41 }],      "businessBookings": null,      "businessFoodOrders": null,      "businessFoodMenuClicks": null    }  }}
SeriesMeaning
totalImpressions, search plus maps.
search, mapsImpressions in Google Search and Google Maps.
directionsAction, phoneAction, websiteActionDirection requests, call clicks, website clicks.
businessBookings, businessFoodOrders, businessFoodMenuClicksBookings, food orders and menu clicks, for profiles that offer them.

A malformed location id returns 200 with googleInsights: null and an errors array, which looks like a disconnected profile. Check errors first.

2. Read Facebook metrics

GET .../facebook-analytics has the same shape under data.facebookInsights with five daily series: views, ctaAction, directionsAction, phoneAction and websiteAction.

Facebook
curl "https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/facebook-analytics?fromDate=2026-08-01&toDate=2026-08-31" \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "data": {    "facebookInsights": {      "views": [{ "startTime": "2026-08-01T00:00:00+00:00", "value": 120 }],      "ctaAction": [{ "startTime": "2026-08-01T00:00:00+00:00", "value": 5 }],      "directionsAction": [{ "startTime": "2026-08-01T00:00:00+00:00", "value": 3 }],      "phoneAction": [{ "startTime": "2026-08-01T00:00:00+00:00", "value": 2 }],      "websiteAction": [{ "startTime": "2026-08-01T00:00:00+00:00", "value": 9 }]    }  }}

ctaAction counts clicks on the Page's call-to-action button, which is how you measure a "Book now" or "Call now" campaign. There is no page-likes metric.

3. Read Bing views

GET .../bing-analytics returns a single series, data.bingInsights.views, bucketed by week rather than day. Data refreshes each Monday for the previous week, so fetch a multi-month range for a trend line.

Bing
curl "https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/bing-analytics?fromDate=2026-06-01&toDate=2026-08-31" \-H "Authorization: API $LISTINGSAPI_KEY"
JSON
{  "data": {    "bingInsights": {      "views": [        { "startTime": "2026-06-01T00:00:00+00:00", "value": 73 },        { "startTime": "2026-06-08T00:00:00+00:00", "value": 58 }      ]    }  }}

Unlike Google and Facebook, Bing reports no data as an empty views array rather than null. Treat both as "nothing to show".

4. Sum a series into a monthly total

Fetch the month, then add the value of every point. Keep null distinct from zero: a disconnected profile must read as "unavailable", not as a month with no traffic. The Node SDK's analytics page has the same sumSeries helper.

Monthly total
# jq: null when the metric is null, otherwise the sum of valuescurl -s "https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/google-analytics?fromDate=2026-08-01&toDate=2026-08-31" \-H "Authorization: API $LISTINGSAPI_KEY" \| jq '.data.googleInsights | { search: (if .search == null then null else ([.search[].value] | add) end),                               maps: (if .maps == null then null else ([.maps[].value] | add) end) }'

Bing needs one extra check: an empty views array sums to 0, so test for length == 0 if you want to show "no data" there too.

5. Compare two periods

Fetch the same metric for two ranges of equal length and compute the change from the two totals. The API has no built-in comparison for profile analytics; the delta fields exist only on review analytics.

Two periods
curl -s "https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/google-analytics?fromDate=2026-07-01&toDate=2026-07-31" \-H "Authorization: API $LISTINGSAPI_KEY" | jq '[.data.googleInsights.total[].value] | add' curl -s "https://listingsapi.com/api/v4/locations/TG9jYXRpb246MTgwMDI4OQ==/google-analytics?fromDate=2026-08-01&toDate=2026-08-31" \-H "Authorization: API $LISTINGSAPI_KEY" | jq '[.data.googleInsights.total[].value] | add'

Guard the three awkward cases: either period null (not connected), the earlier period 0 (division by zero), and a range that is still in progress, since a partial month compared with a full one always looks like a drop. Each call counts against your rate limit, so cache the earlier period rather than refetching it on every render.

Next steps