Messaging
Send and receive real-time events between your app and the XCJ journey using a shared postMessage-based event contract, across Web, iOS, Android, and React Native.
Overview
Once a journey is embedded, your app and the journey communicate over a message-passing channel: window.postMessage on web, or the equivalent native WebView message bridge on iOS, Android, and React Native.
Use messaging to:
React to journey lifecycle events (ready, complete, error, navigation) without polling.
Show or hide the journey from your own UI (e.g. a "Get travel insurance" trigger button).
Exchange offer data with the journey: request an offer, receive the offer response, and observe what the customer selects.
Detect purchase completion and pick up the booking reference for your own records.
Messaging is for non-PII, operational data only. Cover Genius never sends customer personal data through this channel; PII exchange stays server to server, per Data Exchange. The same rule applies to what you send: do not put customer PII into CG_JOURNEY_OFFER_UPDATE.changes or any other outbound payload.
How it works
Every message, in both directions, is a small JSON envelope:
{
"source": "xcover-journeys",
"type": "CG_JOURNEY_READY",
"payload": {}
}source
"xcover-journeys"
Constant. Used to distinguish journey messages from any other traffic on your channel.
type
string
The event name. See the tables below for the full list.
payload
object
Event-specific data. Empty object ({}) for events that carry no data.
There is currently no version field in the envelope. Treat type as the contract; new event types will be additive, and existing payload shapes will not change in a breaking way without a new type.
There is no READY-then-request handshake requirement.
You do not need to wait for CG_JOURNEY_READY before sending inbound events. The journey buffers early messages per event type (up to 10 messages, oldest dropped first once the cap is hit) and delivers them once it starts listening.
Waiting for CG_JOURNEY_READY first is still the simplest mental model and is recommended, but not required for correctness.
Events reference
Event names are exact string values sent in the type field. They are case sensitive.
Outbound, journey to your app
Event (type)
When it fires
Payload
CG_JOURNEY_READY
Once, automatically, when the journey has mounted and is ready to receive messages.
{}
CG_JOURNEY_COMPLETE
The journey has reached a terminal state: the customer purchased, declined, or an unrecoverable error occurred.
outcome: "purchased" | "declined" | "error", policy_id?: string (present when outcome is "purchased")
CG_JOURNEY_ERROR
An error occurred inside the journey.
code: "API_ERROR" | "RENDER_ERROR", message: string
CG_JOURNEY_NAVIGATE
The journey wants the host app to navigate (e.g. a "return to site" link inside the journey).
direction: "back" | "home" | "forward", url?: string
CG_JOURNEY_OFFER_RESPONSE
Sent in reply to a CG_JOURNEY_OFFER_REQUEST, containing the offer built for the customer.
offer_id: string, currency: string, products: OfferResponseProduct[], each with id: string, type: string, price: number | null, price_formatted: string | null
CG_JOURNEY_OFFER_SELECTION
The customer changed their product/option selection within the offer (before submitting).
selectedOption: string | undefined, selectedProductIDs: string[], offer_id: string
CG_JOURNEY_PRODUCT_SELECTED
The customer submitted/confirmed a product selection.
selectedOption: string, selectedProductIDs: string[], offer_id: string
CG_JOURNEY_OFFER_DECLINED
The customer explicitly declined the offer.
offer_id: string
CG_JOURNEY_PAYMENT
Payment for the offer has been taken.
booking_reference: string
Inbound, your app to journey
Event (type)
Purpose
Payload
CG_JOURNEY_SHOW
Show the journey (if you control its visibility from your own UI).
{}
CG_JOURNEY_HIDE
Hide the journey.
{}
CG_JOURNEY_OFFER_REQUEST
Ask the journey to build/return an offer. Triggers a CG_JOURNEY_OFFER_RESPONSE in reply.
product_type?: string, locale?: string
CG_JOURNEY_OFFER_UPDATE
Update an existing offer in place (e.g. changed booking context).
offer_id: string, changes: Record<string, unknown>
CG_JOURNEY_REQUIRE_SELECTION
Tell the journey a product selection is mandatory before the customer can proceed.
offer_id: string
Errors
There is a single application-level error event, sent outbound only:
code
Meaning
Suggested handling
API_ERROR
The journey failed to complete an API call it depends on (e.g. quote, booking).
Surface a generic "something went wrong" state on your side; do not retry automatically from the host.
RENDER_ERROR
The journey failed to render.
Treat as a fallback trigger, for example redirecting the customer to a non-embedded fallback flow if you have one.
message is a human readable description intended for logging and debugging, not for displaying to customers verbatim.
There is currently no inbound error event. Your app cannot signal an error state into the journey over this channel.
Silent failure modes to be aware of
These do not raise an error event. They fail silently by design, so integrations should be tested against them directly:
Your origin/channel is not on the journey's trusted allowlist
The journey drops the message. Nothing is delivered to your listeners, and no error event is sent back to you.
You send a message with a malformed envelope (missing source/type, or payload is null)
The journey ignores it silently.
Transport-level misconfiguration (wrong target origin on web, bridge not registered on mobile)
The message is never delivered at all. This is a platform transport behavior, not journey-specific.
FAQ
Do I need to wait for CG_JOURNEY_READY before sending events to the journey?
No. Early inbound messages are buffered and delivered once the journey starts listening. Waiting for
READYfirst is simpler to reason about and still recommended, but not required.
Is there a way to know why a message I sent wasn't received?
Not from your app. If your origin/channel isn't trusted, or your envelope is malformed, the message is dropped without any error sent back to you. Verify your setup with your integration manager, and check the envelope shape (
source,type,payload) against the reference above.
Can I send arbitrary custom events on this channel?
No.
typemust be one of the documented event names, andsourcemust be"xcover-journeys". Unrecognized types are ignored.
Is this channel used for PII?
No. Keep customer personal data out of these payloads entirely; PII exchange is server to server per Data Exchange.
Is the protocol different on mobile?
No. Same envelope, same event names, same payloads. Only the transport differs; see the platform-specific installation page for how to send and receive the envelope on Web, iOS, Android, or React Native.
Last updated
Was this helpful?

