Bridge Protocol
Raw postMessage contract between Retor and the host. Use this if you're integrating from a framework the SDKs don't cover.
Envelope
Every message uses the same envelope:
{
"source": "retor" | "retor-host",
"type": "...",
"payload": { ... }
}source: "retor" — messages from Retor to the host.source: "retor-host" — messages from the host to Retor.
Always check source before handling. Other apps on the page may also be using postMessage.
Outbound (Retor → host)
init
Fires once when the project data is loaded.
{
"source": "retor",
"type": "init",
"payload": {
"project": {
"_id": "...",
"name": "...",
"description": "...",
"startViewId": "..."
},
"lines": [
{
"_id": "...",
"name": "...",
"description": "...",
"subtitle": "...",
"autoplay": false,
"autoplaySpeed": 1,
"scrollType": "observe" | "track",
"closed": false,
"notesSupported": false,
"tags": [
{
"_id": "...",
"name": "...",
"description": "...",
"subtitle": "...",
"index": 0,
"position": { "x": 0, "y": 0, "z": 0 },
"split": false,
"color": "#...",
"tagType": "bubble",
"iconName": null
}
]
}
]
}
}line-open
A line's scroll path was entered.
{ "source": "retor", "type": "line-open", "payload": { "lineId": "..." } }line-close
The user left the current line.
{ "source": "retor", "type": "line-close" }line-progress
Fires continuously (RAF) while inside a line.
{
"source": "retor",
"type": "line-progress",
"payload": {
"progress": 0.423,
"closestTagId": "..."
}
}Inbound (host → Retor)
open-line
Enter a line's scroll path.
{ "source": "retor-host", "type": "open-line", "payload": { "lineId": "..." } }exit-line
Leave the current line.
{ "source": "retor-host", "type": "exit-line" }scroll-to-tag
Jump the camera along the current line's path to a specific tag.
{ "source": "retor-host", "type": "scroll-to-tag", "payload": { "tagId": "..." } }toggle-autoplay
Toggle the playing state.
{ "source": "retor-host", "type": "toggle-autoplay" }set-autoplay
Explicitly set the playing state.
{ "source": "retor-host", "type": "set-autoplay", "payload": { "playing": true } }set-notes
Push an array of user-generated notes (same shape as tags) into the scene. Retor merges them into the active line's tag list. Send again with an updated array to sync changes.
{
"source": "retor-host",
"type": "set-notes",
"payload": {
"notes": [
{
"_id": "note-1",
"name": "Loose rock",
"description": "Watch the flake",
"position": { "x": 1.2, "y": 3.4, "z": 5.6 },
"objectId": "line-abc"
}
]
}
}Vanilla Mode
Append ?vanilla=true to the preview URL to hide Retor's built-in UI:
https://retor.app/p/abc123?vanilla=trueOnly the 3D scene is rendered — the bridge still works for events and commands.
Raw iframe example
<iframe id="retor" src="https://retor.app/p/abc123?vanilla=true" style="width:100%;height:100%;border:0"></iframe>
<script>
const iframe = document.getElementById("retor");
// Receive
window.addEventListener("message", (e) => {
if (e.data?.source !== "retor") return;
console.log(e.data.type, e.data.payload);
});
// Send — wait for load before posting
iframe.addEventListener("load", () => {
iframe.contentWindow.postMessage(
{ source: "retor-host", type: "open-line", payload: { lineId: "..." } },
"*"
);
});
</script>