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
| Field | Type | Required | Description |
|---|---|---|---|
platform | string | Yes | okendo, judgeme, or yotpo |
api_key | string | Yes | Platform API key |
api_user_id | string | Okendo only | Okendo subscriber ID |
api_secret | string | Yotpo only | Yotpo API secret |
shop_domain | string | Judge.me only | Your .myshopify.com domain |
full_sync | boolean | No | Import all existing reviews (default: true) |
start_bulk_ingest | boolean | No | Start 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
} | Field | Type | Description |
|---|---|---|
platform | string | Platform to disconnect |
delete_reviews | boolean | If 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.
| Status | Error | Meaning |
|---|---|---|
| 409 | already_connected | A key exists and rotate wasn’t true. The current key keeps working. Normally doesn’t count toward the limit. |
| 403 | entitlement_required | Your plan doesn’t include this integration. Normally doesn’t count toward the limit. |
| 429 | rate_limited | 5 keys per 24 hours per partner, shared with the Integrations card. |
| 404 | store_not_found | The key’s store no longer exists. |
| 500 | internal_error | Unexpected 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.
Book a demo