Integrations API

Last updated: October 17, 2026

Connect third-party review platforms to import existing reviews and receive new ones via webhooks.

Connect Platform

POST /api/v1/reviews/connect

Connects a review platform and optionally starts a full review import.

Request (Okendo)

{
  "platform": "okendo",
  "api_key": "YOUR_OKENDO_API_KEY",
  "api_user_id": "YOUR_OKENDO_SUBSCRIBER_ID",
  "full_sync": true,
  "start_bulk_ingest": true
}

Request (Judge.me)

{
  "platform": "judgeme",
  "api_key": "YOUR_JUDGEME_TOKEN",
  "shop_domain": "yourstore.myshopify.com",
  "full_sync": true
}

Request (Yotpo)

{
  "platform": "yotpo",
  "api_key": "YOUR_YOTPO_KEY",
  "api_secret": "YOUR_YOTPO_SECRET",
  "full_sync": true
}

Parameters

FieldTypeRequiredDescription
platformstringYesokendo, judgeme, or yotpo
api_keystringYesPlatform API key
api_user_idstringOkendo onlyOkendo subscriber ID
api_secretstringYotpo onlyYotpo API secret
shop_domainstringJudge.me onlyYour .myshopify.com domain
full_syncbooleanNoImport all existing reviews (default: true)
start_bulk_ingestbooleanNoStart import immediately (default: true)

Response (201)

{
  "message": "Connected to okendo successfully",
  "platform": "okendo",
  "credential_id": 5,
  "credentials_verified": true,
  "webhook_url": "https://api.betterreviews.app/api/v1/reviews/webhooks/okendo",
  "webhook_events": ["review.created", "review.updated"],
  "ingestion_started": true,
  "ingestion_job_id": "uuid"
}

Disconnect Platform

POST /api/v1/reviews/disconnect

Request

{
  "platform": "okendo",
  "delete_reviews": false
}
FieldTypeDescription
platformstringPlatform to disconnect
delete_reviewsbooleanIf true, deletes all imported reviews from that platform

List Active Connections

GET /api/v1/reviews/platforms/credentials

Returns all active platform connections for your store.


Webhook Management

Subscribe

POST /api/v1/reviews/webhooks/subscribe

Register a webhook with the review platform to receive new reviews automatically.

Request

{
  "platform": "okendo",
  "events": ["review.created", "review.updated"]
}

List Subscriptions

GET /api/v1/reviews/webhooks/subscriptions

Unsubscribe

DELETE /api/v1/reviews/webhooks/unsubscribe/:platform


How Review Import Works

When full_sync: true, the system pages through all reviews from the platform API and imports them. Large catalogs (300K+ reviews) may take several minutes. Reviews are deduplicated by external review ID, so re-running is safe.

New reviews after the initial import arrive via webhooks automatically — no polling needed.


Partner Integrations (Reactiv, PDQ)

Create the key a partner uses to read your store’s reviews — the same key the Settings → Integrations card makes. :partner is reactiv or pdq; anything else returns 404 unknown_partner.

Auth: a store API key only. Session tokens, the bot key and storeless keys get 403 store_api_key_required. Connect and disconnect need a Read & Write key; state works with a Read-only key.

Don’t create a general key named reactiv or pdq — POST /api/v1/user/api-keys and POST /api/v1/tokens both refuse it with 422, and a general key never works on a partner’s endpoints.

Get state

GET /api/v1/integrations/:partner

{
  "state": "connected",
  "key": {"prefix": "ppo_AbCd", "created_at": "2026-10-17T10:00:00Z", "last_used_at": null},
  "entitled": true
}

state is disconnected, connected, or plan_stripped (key exists but the plan lost the integration). key is null when disconnected. Reactiv also returns last_sync_at. The raw key is never returned here.

Connect

POST /api/v1/integrations/:partner/connect

{"rotate": false}

Set rotate to true to replace an existing key; the old one stops working immediately.

Response (200, Cache-Control: no-store)

{"key": "ppo_...", "prefix": "ppo_AbCd", "created_at": "2026-10-17T10:00:00Z"}

The raw key is shown once. It has no expiry and stays valid even after the key that created it is revoked or expires; to turn it off, call disconnect.

StatusErrorMeaning
409already_connectedA key exists and rotate wasn’t true. The current key keeps working. Normally doesn’t count toward the limit.
403entitlement_requiredYour plan doesn’t include this integration. Normally doesn’t count toward the limit.
429rate_limited5 keys per 24 hours per partner, shared with the Integrations card.
404store_not_foundThe key’s store no longer exists.
500internal_errorUnexpected failure; retry later.

Disconnect

POST /api/v1/integrations/:partner/disconnect

Revokes the key. Idempotent: an already-disconnected store also gets {"status": "disconnected"}. Works on any plan. 5 per 24 hours, shared with the card.

Every connect and disconnect through the API notifies the BetterReviews team.