> ## Documentation Index
> Fetch the complete documentation index at: https://docs.neariq.io/llms.txt
> Use this file to discover all available pages before exploring further.

# GBP

> Session-authenticated Google Business Profile connection, review, reply, and posting endpoints.

GBP endpoints power the dashboard connection flow for Google Business Profile. They use the signed-in app session, not `X-NearIQ-Key`, and operate on the user's active accessible business.

<Note>
  These endpoints are not public v1 API-key endpoints. They require an authenticated dashboard session and may return `401` when the session is missing.
</Note>

## GET /api/gbp/connect

Starts the OAuth connection flow and redirects the browser to the consent screen.

<RequestExample>
  ```bash cURL theme={null}
  curl -i "https://app.neariq.io/api/gbp/connect?returnTo=/settings?tab=business" \
    -H "Cookie: <dashboard session cookie>"
  ```
</RequestExample>

<ParamField query="returnTo" type="string">
  Optional relative path to return to after a successful connection. Non-relative values are ignored.
</ParamField>

<ParamField query="includeSheets" type="string">
  Set to `1` when the user is explicitly authorizing spreadsheet export access in the same flow.
</ParamField>

<ParamField query="scope" type="string">
  Set to `sheets` as an alternate way to include spreadsheet export access.
</ParamField>

Successful responses redirect to the OAuth consent screen. Missing app integration configuration returns:

```json theme={null}
{
  "error": "GBP integration not configured."
}
```

## GET /api/gbp/callback

Handles the OAuth callback, verifies the signed-in user matches the state payload, stores encrypted tokens, discovers the first available location, and redirects back to the requested dashboard path.

```bash theme={null}
curl -i "https://app.neariq.io/api/gbp/callback?code=<oauth_code>&state=<state>"
```

Successful callbacks redirect to the return path with `gbp=connected`. Failure redirects include `gbp=error` and a reason such as `missing_code`, `invalid_state`, `auth_mismatch`, `token_exchange_failed`, `no_business`, or `encryption_unavailable`.

## GET /api/gbp/status

Returns the current user's visible GBP connection status.

<RequestExample>
  ```bash cURL theme={null}
  curl "https://app.neariq.io/api/gbp/status" \
    -H "Cookie: <dashboard session cookie>"
  ```
</RequestExample>

```json theme={null}
{
  "connected": true,
  "businessId": "f7f1ec9a-8775-45e0-b09a-4e2de2c9252d",
  "locationTitle": "Aster Grove Fitness",
  "locationName": "locations/123456789",
  "connectedAt": "2026-05-31T10:30:00.000Z"
}
```

When no connection is visible:

```json theme={null}
{
  "connected": false
}
```

## POST /api/gbp/disconnect

Disconnects the visible GBP connection for the active business. Token revocation is best effort; the local connection is removed either way.

```bash theme={null}
curl -X POST "https://app.neariq.io/api/gbp/disconnect" \
  -H "Cookie: <dashboard session cookie>"
```

```json theme={null}
{
  "ok": true,
  "disconnected": true,
  "connected": false,
  "businessId": "f7f1ec9a-8775-45e0-b09a-4e2de2c9252d"
}
```

If there is no visible connection, the response is still successful:

```json theme={null}
{
  "ok": true,
  "disconnected": false,
  "connected": false
}
```

## GET /api/gbp/reviews

Fetches reviews for the active connected location and normalizes them for the dashboard review reply flow.

```bash theme={null}
curl "https://app.neariq.io/api/gbp/reviews" \
  -H "Cookie: <dashboard session cookie>"
```

```json theme={null}
{
  "reviews": [
    {
      "reviewName": "accounts/123/locations/456/reviews/abc",
      "rating": 5,
      "text": { "text": "Best class in town." },
      "authorAttribution": {
        "displayName": "Jane D.",
        "photoUri": "https://example.com/avatar.jpg"
      },
      "relativePublishTimeDescription": "",
      "publishTime": "2026-05-30T18:00:00Z",
      "ownerResponse": "Thank you Jane.",
      "ownerResponseDate": "2026-05-30T19:00:00Z"
    }
  ],
  "ownerResponseRate": 72
}
```

If the active business is missing or not connected, the route returns an empty review array with an explanatory `error` value.

## POST /api/gbp/reply

Posts or updates a reply to a GBP review.

```bash theme={null}
curl -X POST "https://app.neariq.io/api/gbp/reply" \
  -H "Content-Type: application/json" \
  -H "Cookie: <dashboard session cookie>" \
  -d '{
    "reviewName": "accounts/123/locations/456/reviews/abc",
    "comment": "Thank you for visiting Aster Grove Fitness."
  }'
```

<ParamField body="reviewName" type="string" required>
  Full review resource name returned by `GET /api/gbp/reviews`.
</ParamField>

<ParamField body="comment" type="string">
  Reply text. Either `comment` or `reply` is accepted.
</ParamField>

<ParamField body="reply" type="string">
  Alternate reply text field kept for legacy clients.
</ParamField>

```json theme={null}
{
  "ok": true,
  "reply": {
    "comment": "Thank you for visiting Aster Grove Fitness.",
    "updateTime": "2026-05-31T10:45:00Z"
  }
}
```

Org-owned businesses require the `review_responses_post` permission.

## DELETE /api/gbp/reply

Deletes a reply from a GBP review. `DELETE /api/gbp/reviews/reply` is an alias for the same handler.

```bash theme={null}
curl -X DELETE "https://app.neariq.io/api/gbp/reply" \
  -H "Content-Type: application/json" \
  -H "Cookie: <dashboard session cookie>" \
  -d '{ "reviewName": "accounts/123/locations/456/reviews/abc" }'
```

```json theme={null}
{
  "ok": true
}
```

## POST /api/gbp/post

Creates a local post for the active connected GBP location.

<Note>
  This endpoint requires a plan with `gbpAutoPost` access. Org-owned businesses also require the `social_media_publish` permission.
</Note>

```bash theme={null}
curl -X POST "https://app.neariq.io/api/gbp/post" \
  -H "Content-Type: application/json" \
  -H "Cookie: <dashboard session cookie>" \
  -d '{
    "summary": "Join us this Saturday for a free intro class.",
    "callToAction": {
      "actionType": "SIGN_UP",
      "url": "https://example.com/intro"
    },
    "mediaUrl": "https://example.com/class-photo.jpg"
  }'
```

<ParamField body="summary" type="string" required>
  Post text. Must be 1-1500 characters.
</ParamField>

<ParamField body="callToAction.actionType" type="string">
  One of `BOOK`, `ORDER`, `SHOP`, `LEARN_MORE`, `SIGN_UP`, or `CALL`.
</ParamField>

<ParamField body="callToAction.url" type="string">
  Optional CTA URL.
</ParamField>

<ParamField body="mediaUrl" type="string">
  Optional public image URL.
</ParamField>

```json theme={null}
{
  "success": true,
  "postName": "accounts/123/locations/456/localPosts/789",
  "state": "LIVE",
  "createTime": "2026-05-31T10:50:00Z"
}
```

## POST /api/gbp/bulk-post

Creates the same local post for multiple owned business locations.

```bash theme={null}
curl -X POST "https://app.neariq.io/api/gbp/bulk-post" \
  -H "Content-Type: application/json" \
  -H "Cookie: <dashboard session cookie>" \
  -d '{
    "businessIds": [
      "f7f1ec9a-8775-45e0-b09a-4e2de2c9252d",
      "0f3a7347-bdb5-44fd-8f1e-9f1fbb15c553"
    ],
    "summary": "New weekend classes are open for booking.",
    "callToAction": { "actionType": "BOOK" }
  }'
```

<ParamField body="businessIds" type="array" required>
  Owned business IDs to post to. The route accepts 1-50 IDs.
</ParamField>

<ParamField body="summary" type="string" required>
  Post text. Must be 1-1500 characters.
</ParamField>

```json theme={null}
{
  "results": [
    {
      "businessId": "f7f1ec9a-8775-45e0-b09a-4e2de2c9252d",
      "businessName": "Aster Grove Fitness",
      "success": true
    }
  ],
  "summary": {
    "total": 1,
    "success": 1,
    "failed": 0
  }
}
```

Bulk posting requires a plan with `gbpAutoPost` access and only posts to businesses owned by the signed-in user.
