Window messages
Use window.postMessage() to exchange state between your host page and the iC Candle iframe.
Always verify event.origin === "https://embed-iccandle-app.iccandle.ai" on inbound messages. Parent -> embed messages should use that same origin as targetOrigin.
Message transport
Embed messages may arrive in either of these forms:
- Plain JavaScript objects
- JSON strings that need
JSON.parse()
Normalize event.data before routing:
const EMBED_ORIGIN = "https://embed-iccandle-app.iccandle.ai";
window.addEventListener("message", (event) => {
if (event.origin !== EMBED_ORIGIN) return;
let message;
try {
message =
typeof event.data === "string" ? JSON.parse(event.data) : event.data;
} catch {
return;
}
handleEmbedMessage(message);
});
Parent -> embed
parent-origin
Tell the iframe which parent origin should be used for Stripe checkout return URLs.
type ParentOriginMessage = {
type: "parent-origin";
origin: string;
};
Example:
iframe.contentWindow.postMessage(
{ type: "parent-origin", origin: window.location.origin },
EMBED_ORIGIN,
);
payment-success
Notify the iframe after Stripe redirects back to your host page.
type PaymentSuccessMessage = {
type: "payment-success";
};
Example:
iframe.contentWindow.postMessage({ type: "payment-success" }, EMBED_ORIGIN);
Embed -> parent
Iframe messages use a name + data envelope:
type EmbedMessageEnvelope = {
name?: string;
data?: unknown;
pattern?: unknown;
};
name messages
name | Payload shape | When it fires | Host action |
|---|---|---|---|
auth.signIn | { name: "auth.signIn", data: { idToken: string } } | Sign-in completes inside the iframe | Store data.idToken as iccandle_token if your host will call iC Candle APIs |
selector.loading | { name: "selector.loading", data: { isLoading: boolean } } | Scan or AI preparation starts or finishes | Show or hide loading UI |
chart.play | { name: "chart.play", data: { isReplay: true, predictCandles?: Candle[] | null, playEndTimestamp: number | null, selectedCandles: Candle[] | null } } | User starts replay from chart or news flows | Inject replay bars or generated candles |
chart.stop | { name: "chart.stop", data: { isReplay: false, predictCandles?: Candle[] | null, playEndTimestamp: null, selectedCandles: null } } or { name: "chart.stop", data: null } | Replay is cleared or closed | Remove replay candles and replay-only overlays |
selector.closeResult | { name: "selector.closeResult", data: null } | Active scan result panel closes | Clear result-specific overlays |
nav.click | { name: "nav.click", data: { href: string } } | User clicks embed header navigation | Optionally react to tab or route changes |
news.eventClicked | { name: "news.eventClicked", data: { event: NewsEvent, similarDetails: object | null } } | User selects an economic event | Center chart on the event and draw related markers |
news.selectedEventPayloads | { name: "news.selectedEventPayloads", data: NewsEvent[] } | User selects scanner news events | Persist selected events for timescale marks or overlays |
news.back | { name: "news.back", data: null } | User leaves news detail | Clear event-specific chart decorations |
news.backToSimilarEvents | { name: "news.backToSimilarEvents", data: null } | User navigates back inside similar-events flow | Same cleanup as news.back |
news.iframeReady | { name: "news.iframeReady", data: null } | Similar-events iframe finishes initial load | Optional lifecycle hook |
news.analyzeImpact | { name: "news.analyzeImpact", data: null } | User requests impact analysis | Optional analysis hook |
playEndTimestamp uses unix seconds.
Pattern-selection messages
Pattern flows also use the name + data envelope:
| Shape | When it fires | Host action |
|---|---|---|
{ name: "pattern.classicPatternSelected", data: { pattern: object } } | User selects a classic/common pattern match | Highlight the compared pattern range |
{ name: "pattern.clearClassicPatternSelected", data: null } | User clears the classic/common selection | Remove the highlight |
{ name: "pattern.custom_pattern_selected", data: { pattern: object } } | User selects a tracked pattern | Highlight the tracked pattern range |
{ name: "pattern.clear_custom_pattern_selected", data: null } | User clears tracked-pattern selection | Remove the tracked highlight |
Your host usually only needs each pattern's start and end timestamps, or whichever equivalent range fields your charting library expects.
Recommended router
When handling iframe output, route by message.name.
Next
See Data types for shared payload shapes like Candle, NewsEvent, replay payloads, and auth message bodies.