Skip to main content

Partner Integration Requirement

Partner only needs:
  1. One line of code integration
  2. One API call before booking
That is the full BRG Radar V2 integration.

What We Provide vs What Partner Provides

PageOne Travel provides

  • collector-key (for browser signal collection only)
  • api-key (for server-to-server risk check call)
  • API host and snippet URL

Partner provides

  • session-id (unique per booking attempt)
  • Booker/guest data for the check request
  • Backend call to POST /api/v1/radar/checks before creating booking

1) One Line of Code Integration (Snippet)

Add this on the partner booking page:
<script async src="https://cdn.pageonetravel.com/brg/radar.min.js" data-session-id="{{SESSION_ID}}" data-collector-key="{{COLLECTOR_KEY}}"></script>
Notes:
  • Use a fresh SESSION_ID per booking attempt.
  • Do not put api-key in browser code.
  • data-partner-id is not required.

2) One API Call Before Booking

Call this from partner backend before booking confirm:
POST /api/v1/radar/checks

Headers

HeaderRequiredDescription
Content-TypeYesapplication/json
api-keyYesPartner server API key issued by PageOne
session-idYesSame value used in snippet
idempotency-keyNoRecommended for retry safety

Request body (example)

{
  "trigger_event": "booking_before_payment",
  "booker": {
    "first_name": "John",
    "last_name": "Smith",
    "email": "john@example.com",
    "phone": "+12065550123"
  },
  "guest": {
    "first_name": "John",
    "last_name": "Smith"
  },
  "context": {
    "partner_request_id": "req_20260219_001",
    "booker_uuid": "u_abc123",
    "user_id": "12345",
    "ip": "198.51.100.10"
  },
  "payment": {
    "billing_address": {
      "line1": "123 Main St",
      "city": "Seattle",
      "state": "WA",
      "postal_code": "98101",
      "country": "US"
    }
  },
  "extras": {
    "channel": "web"
  }
}
inventory_id and inventory_country are not required from partner in BRG integration.

Response body (example)

{
  "data": {
    "check_id": "chk_2b89f17f008a4f7a94ef90f9",
    "partner_id": "p_xxx",
    "session_id": "sess_001",
    "decision": "deny",
    "radar_result": "banned",
    "should_hide_rate": true,
    "billable": true,
    "checked_at": "2026-02-19T23:35:46.177Z"
  },
  "message": "success"
}
Decision handling:
  • decision = deny: hide the rate / stop booking flow
  • decision = allow or bypass: continue booking flow

How Correlation Works

  • Snippet and check API must share the same session-id.
  • Snippet posts browser/device/network hints first.
  • Check API merges that signal set with server payload and returns one risk decision.

Security Model (Two Keys)

  • collector-key: browser-side, limited to signal collection endpoint.
  • api-key: server-side, required for POST /api/v1/radar/checks.
Do not use api-key in frontend code.

Optional: Manual Collector Test (Browser Fetch)

If you want to simulate snippet behavior:
fetch("https://<your-host>/api/v1/radar/sessions/signals", {
  method: "POST",
  headers: {
    "content-type": "application/json",
    "session-id": "sess_001",
    "x-brg-collector-key": "<collector-key>"
  },
  body: JSON.stringify({
    page_url: location.href,
    referrer: document.referrer,
    user_agent: navigator.userAgent,
    language: navigator.language,
    timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
    screen: {
      width: window.screen.width,
      height: window.screen.height,
      pixel_ratio: window.devicePixelRatio
    },
    device: {
      platform: navigator.platform,
      hardware_concurrency: navigator.hardwareConcurrency,
      touch_points: navigator.maxTouchPoints || 0
    },
    fingerprint: {
      visitor_id: "vis_demo_001"
    }
  })
});