Partner Integration
Core Chat API Documentation
Overview and quickstart for Brek Partner Core Chat. Endpoint-level reference now lives in dedicated pages for faster scanning.
Create a partner chat session.
View endpointSend one user turn or explicit action event to an existing session.
View endpointFetch current session snapshot and event history.
View endpointStart here
Brek Partner Core Chat API lets you embed Brek's hotel search and booking assistant in your own product.
Onboarding:
- Contact
leo@pageonelab.com. - Brek issues your partner API key and sandbox base URL.
- Run the quickstart below and then move to endpoint details.
Last updated: February 24, 2026.
5-minute quickstart (cURL)
Prerequisites:
- Partner API key
- Brek base URL
curlandjq
Set env vars:
export BREK_BASE_URL="https://www.brek.ai"
export BREK_PARTNER_API_KEY="<your_partner_api_key>"
export ACTOR_ID="partner_user_001"
- Create a session:
SESSION_ID=$(curl -sS "$BREK_BASE_URL/api/partner/v1/core-chat/sessions" \
-H "x-partner-api-key: $BREK_PARTNER_API_KEY" \
-H "content-type: application/json" \
-d "{\"actor\":{\"actorId\":\"$ACTOR_ID\",\"timezoneOffsetMinutes\":-480},\"channel\":{\"workspaceId\":\"partner-workspace\"},\"conversation\":{\"channelId\":\"partner-chat\"}}" \
| jq -r '.data.sessionId')
echo "SESSION_ID=$SESSION_ID"
- Send a user turn:
curl -sS "$BREK_BASE_URL/api/partner/v1/core-chat/events" \
-H "x-partner-api-key: $BREK_PARTNER_API_KEY" \
-H "content-type: application/json" \
-d "{\"sessionId\":\"$SESSION_ID\",\"text\":\"Seattle Mar 20-23 1 room refundable\",\"idempotencyKey\":\"demo:$SESSION_ID:search:001\"}" \
| jq
- Read latest session snapshot:
curl -sS "$BREK_BASE_URL/api/partner/v1/core-chat/sessions/$SESSION_ID" \
-H "x-partner-api-key: $BREK_PARTNER_API_KEY" \
| jq
Quickstart (Node.js)
const baseUrl = process.env.BREK_BASE_URL!;
const apiKey = process.env.BREK_PARTNER_API_KEY!;
async function call(path: string, init?: RequestInit) {
const res = await fetch(`${baseUrl}${path}`, {
...init,
headers: {
'content-type': 'application/json',
'x-partner-api-key': apiKey,
...(init?.headers ?? {})
}
});
const body = await res.json();
if (!res.ok) throw new Error(JSON.stringify(body));
return body;
}
const session = await call('/api/partner/v1/core-chat/sessions', {
method: 'POST',
body: JSON.stringify({
actor: { actorId: 'partner_user_001', timezoneOffsetMinutes: -480 },
channel: { workspaceId: 'partner-workspace' },
conversation: { channelId: 'partner-chat' }
})
});
const sessionId = session.data.sessionId;
const event = await call('/api/partner/v1/core-chat/events', {
method: 'POST',
body: JSON.stringify({
sessionId,
text: 'Seattle Mar 20-23 1 room refundable',
idempotencyKey: `demo:${sessionId}:search:001`
})
});
console.log(event.data.result.status);
Quickstart (Python)
import os
import requests
base_url = os.environ["BREK_BASE_URL"]
api_key = os.environ["BREK_PARTNER_API_KEY"]
headers = {
"x-partner-api-key": api_key,
"content-type": "application/json",
}
session_res = requests.post(
f"{base_url}/api/partner/v1/core-chat/sessions",
headers=headers,
json={
"actor": {"actorId": "partner_user_001", "timezoneOffsetMinutes": -480},
"channel": {"workspaceId": "partner-workspace"},
"conversation": {"channelId": "partner-chat"},
},
timeout=20,
)
session_res.raise_for_status()
session_id = session_res.json()["data"]["sessionId"]
event_res = requests.post(
f"{base_url}/api/partner/v1/core-chat/events",
headers=headers,
json={
"sessionId": session_id,
"text": "Seattle Mar 20-23 1 room refundable",
"idempotencyKey": f"demo:{session_id}:search:001",
},
timeout=20,
)
event_res.raise_for_status()
print(event_res.json()["data"]["result"]["status"])
Machine-readable resources
For agent/tool integrations, use these directly:
- OpenAPI:
https://www.brek.ai/openapi/partner-core-chat-v1.yaml - LLM index:
https://www.brek.ai/llms.txt - Human docs page:
https://www.brek.ai/docs/partner-core-chat
If you self-host, use the same paths on your own domain:
/openapi/partner-core-chat-v1.yaml/llms.txt
API conventions
Base path:
/api/partner/v1/core-chat
Standard request headers:
content-type: application/json- one partner auth header (see Authentication section)
Common response headers (successful authenticated calls):
x-request-id: request trace IDx-ratelimit-limit: minute quota for this keyx-ratelimit-remaining: remaining requests in current windowx-partner-id: resolved partner ID
Note:
- For early auth failures (
401,403),x-request-idis guaranteed; other headers may be absent.
Success envelope:
{
"data": {
"...": "endpoint-specific payload"
}
}
Gateway error envelope:
{
"success": false,
"error": "human-readable message",
"code": "machine_readable_code",
"details": null,
"requestId": "8f6f7d9d-74d5-4f37-8ef8-9c77d4f4ec2b"
}
Validation/proxy error envelope:
{
"success": false,
"error": "human-readable message",
"requestId": "2a5ea99c-9884-448f-a442-35a883b64b31"
}
Authentication
Send one of these headers on every request:
x-partner-api-key: <partner_api_key>(recommended)Authorization: Bearer <partner_api_key>api-key: <partner_api_key>
Auth/quota behavior:
- Missing key ->
401,code=missing_partner_api_key - Invalid key ->
403,code=invalid_partner_api_key - Rate limited ->
429,code=rate_limited
Best practice:
- Keep keys server-side only
- Never expose partner keys in browser/mobile clients
Session model and identity rules
Core objects:
actor.actorId: stable partner-side end-user IDsessionId: Brek session key returned byPOST /sessionsdata.result.status: state machine output for UI/agent branchingdata.result.artifacts: structured payload for your UI logic
Rules:
- Persist
sessionIdbyactorId - Never reuse one
sessionIdacross different users - If you send
actor.actorIdinPOST /events, it must match the session owner
Status-driven integration model
Always branch on data.result.status.
result.status | Meaning | Partner UI/agent action | Key artifacts |
|---|---|---|---|
shortlist | Search candidates ready | Render options and ask user selection | artifacts.shortlist[] |
guest_name_required | Need guest legal name | Ask first + last name | none |
payment_setup_required | No usable card yet | Open setup URL and wait for "done" | artifacts.payment.setupUrl |
payment_confirmation_required | Card found, need consent | Ask user confirm/decline | artifacts.payment.* |
booked | Booking completed | Show confirmation + deep link | artifacts.booking.* |
error | Flow halted | Show fallback + stop write actions | message text |
Idempotency and retry
Retry policy:
- Retry only
429and5xx - Use exponential backoff + jitter
- Keep the same
idempotencyKeyfor retrying the same write action
Idempotency key format recommendation:
<partner>:<sessionId>:<action>:<sequence>- Example:
demo:sess_1771456953407_g7p6233d:book:001
Golden path: no saved card to booked
This sequence was captured from sandbox on February 18, 2026.
Step 0 (POST /sessions): create session
{
"actor": {
"actorId": "partner_golden_user_done",
"timezoneOffsetMinutes": -420
},
"channel": {
"workspaceId": "partner-demo"
},
"conversation": {
"channelId": "partner-chat"
}
}
Step 1 (POST /events): user search
{
"sessionId": "sess_1771456953407_g7p6233d",
"text": "find me a las vegas hotel from 5/15 to 5/16 that is cheap and refundable",
"idempotencyKey": "demo:sess_1771456953407_g7p6233d:search:001"
}
Key output:
result.status=shortlistartifacts.shortlist[]available
Step 2 (POST /events): user asks to book option
{
"sessionId": "sess_1771456953407_g7p6233d",
"text": "can you help me book option 1"
}
Key output:
result.status=guest_name_required
Step 3 (POST /events): user shares guest name
{
"sessionId": "sess_1771456953407_g7p6233d",
"text": "guest name is John Doe"
}
Key output:
result.status=payment_setup_requiredartifacts.payment.setupUrlavailable
Step 4 (outside partner core chat): user attaches card in payment portal
{
"portalToken": "psu_1771456992743_e2634ddd",
"paymentMethodId": "pm_card_visa",
"cardBrand": "visa",
"cardLast4": "4242",
"expMonth": 12,
"expYear": 2030,
"setAsDefault": true
}
Step 5 (POST /events): user returns and says "Done"
{
"sessionId": "sess_1771456953407_g7p6233d",
"text": "Done"
}
Key output:
result.status=payment_confirmation_requiredartifacts.paymentavailable
Step 6 (POST /events): user confirms payment
{
"sessionId": "sess_1771456953407_g7p6233d",
"text": "yes, use this card"
}
Key output:
result.status=bookedartifacts.booking.confirmationUrlavailable
Additional scenarios
User says "Done" before card attach:
- Input:
POST /eventswithtext="Done" - Output:
result.status=payment_setup_requiredand a new setup URL
User already has saved card:
- Input: guest-name turn after booking intent
- Output:
result.status=payment_confirmation_requireddirectly
User declines payment confirmation:
- Input:
POST /eventswithtext="no" - Output:
result.status=errorand booking is not continued
Error catalog
| HTTP | Code | Meaning | Handling |
|---|---|---|---|
400 | invalid_request or validation message | Missing/invalid request fields | Fix request, do not blind retry |
401 | missing_partner_api_key | No API key provided | Fix auth headers |
403 | invalid_partner_api_key | API key not recognized | Rotate/fix key |
404 | session_not_found | Session missing or tenant mismatch | Recreate or remap session |
409 | n/a | Actor mismatch for session owner check | Fix actor/session mapping |
429 | rate_limited | Per-minute quota exceeded | Retry with backoff |
5xx | varies | Unexpected server/proxy issue | Retry with backoff + alerting |
Example (401 missing key):
{
"success": false,
"error": "Missing partner API key.",
"code": "missing_partner_api_key",
"details": null,
"requestId": "d813d7e3-ba0b-4a97-899d-0847590d7560"
}
Example (400 missing idempotencyKey):
{
"success": false,
"error": "idempotencyKey is required for kind=action_book_option",
"requestId": "2a5ea99c-9884-448f-a442-35a883b64b31"
}
Security requirements
- Keep partner API keys server-side only
- Use HTTPS/TLS for all partner traffic
- Do not send raw PCI card data in chat payloads
- Log
x-request-idandrequestIdfor incident triage - Ensure one session is always scoped to one actor
Production checklist
Before production launch:
- Persist
sessionIdbyactorId - Handle every known
result.status - Parse
artifactsdefensively (optional fields) - Implement retry + idempotency policy
- Alert on repeated
401/403/429and5xx - Keep keys in your secret manager
- Validate your integration against OpenAPI before release
Agent integration playbook
Deterministic loop:
- Ensure a session exists (
POST /sessionsonce per actor lifecycle) - Send user turn (
POST /events) - Branch only on
data.result.status - Execute external steps (for example card setup) when required
- Continue until terminal status (
bookedorerror)
Agent guardrails:
- Never assume booking completion without
status=booked - Never call write kinds without
idempotencyKey - Never reuse one session across different actors
- Always propagate
requestIdandtraceIdinto logs - Prefer OpenAPI schema for request shaping and validation
Support
For onboarding, production readiness review, or incident triage:
leo@pageonelab.com