Documentation Index
Fetch the complete documentation index at: https://docs.pageonetravel.com/llms.txt
Use this file to discover all available pages before exploring further.
Partner Integration Requirement
Partner only needs:
- One line of code integration
- 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
| Header | Required | Description |
|---|
Content-Type | Yes | application/json |
api-key | Yes | Partner server API key issued by PageOne |
session-id | Yes | Same value used in snippet |
idempotency-key | No | Recommended 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"
}
})
});