Skip to content
AW
ArchWalk 360/Developer Docs

GET STARTED

  • Overview
  • Quickstart
  • Partner integration

GUIDES

  • Embedded Creator
  • Media
  • Capture guide
  • Viewer

REFERENCE

  • Authentication
  • API Reference
  • Errors & troubleshooting

Embedded Creator

Let sellers edit an Experience directly inside your product.

10. Quickstart C — embedded Creator

  1. Register https://dashboard.acmestay.example as an Integration allowed origin.
  2. Resolve the Experience from your backend (Quickstart A step 1).
  3. Mint a session (never from the browser):
bash
SESSION_JSON=$(curl -sS -X POST "$ARCHWALK_API_BASE/api/v1/360/creator-sessions" \
  -H "Authorization: Bearer $AW360_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"origin\": \"https://dashboard.acmestay.example\",
    \"experience_id\": \"$EXPERIENCE_ID\",
    \"permitted_actions\": [
      \"experiences:read\",
      \"experiences:write\",
      \"experiences:publish\",
      \"panoramas:read\",
      \"panoramas:write\",
      \"panoramas:upload\"
    ]
  }")
export SESSION_API_ID=$(echo "$SESSION_JSON" | jq -r .api_id)
export CREATOR_SESSION_TOKEN=$(echo "$SESSION_JSON" | jq -r .token)
  1. Return SESSION_API_ID and CREATOR_SESSION_TOKEN to your dashboard over your own authenticated API (never the Partner API key).
  2. Iframe src is only the session id, never the token:
html
<iframe
  id="creator"
  title="ArchWalk 360 Creator"
  src="https://YOUR_ARCHWALK_APP_HOST/aw360/c/SESSION_API_ID"
  style="width:100%;height:80vh;border:0"
></iframe>
  1. After creator:ready-for-init, post creator:init with { token } to the Creator origin. See postMessage protocol.


19. Creator session and iframe

Mint — POST /api/v1/360/creator-sessions

Scope creator_sessions:issue. Status 201.

FieldRequiredNotes
originYesParent page origin; must be on the Integration allowlist
permitted_actionsYesNon-empty subset of credential scopes; cannot include creator_sessions:issue
experience_idOne binding requiredOpaque Experience id → binding_kind=experience
external_resource_idOr this, if no experience_idbinding_kind=external_resource (session may exist before an Experience exists)
external_customer_idOptionalMust match the Experience when both are supplied
ttl_secondsOptionalDefault 1800 (30 min), cap 3600 (60 min)

binding_kind is not a request field.

Response includes token once, plus api_id, binding fields, origin, permitted_actions, status, timestamps.

Invalidation: expiry, explicit credential revoke (not rotate), Integration/entitlement/org becoming unusable, or Experience becoming unusable for an experience-bound session.

Parent page sequence

  1. Backend authenticates the hotel user itself.
  2. Backend resolves Experience and mints session.
  3. Dashboard creates iframe src={ARCHWALK_APP_ORIGIN}/aw360/c/{api_id} (no token).
  4. Wait for creator:ready-for-init from event.origin === creatorOrigin and event.source === iframe.contentWindow.
  5. iframe.contentWindow.postMessage(initMessage, creatorOrigin) — exact target origin, never *.
  6. Creator validates parent origin/source and token prefix aw360_cs_{sessionApiId}.…, then calls ArchWalk with Authorization: Bearer {token} and X-AW360-Parent-Origin.
  7. creator:ready — editing can proceed.

Opening /aw360/c/... top-level (not framed) does not complete the handshake.

Creator runtime APIs under /aw360/creator/... are for the ArchWalk iframe, not for your servers.



20. postMessage protocol

This is the Viewer/Creator embed contract implemented by the ArchWalk frontend. Backend OpenAPI does not define these message names; if the frontend protocol changes, this guide must be updated in that same change.

Envelope for all public messages:

json
{
  "source": "archwalk360",
  "version": 1,
  "type": "<type>"
}

Ignore unknown types. Validate source, version, event.origin, and event.source. Always use an exact targetOrigin.

Viewer (public contract)

Parent → Viewer

TypePayloadWhen
initenvelope onlyOptional; establish parent trust if referrer is insufficient

Viewer → Parent

TypePayloadWhen
viewerOpenedpanoramaCount, activePanoramaIndexViewer opened
readypanoramaCount, activePanoramaIndexReady to interact
panoramaChangedactivePanoramaIndex, labelActive panorama changed
interactionkind: pointer | wheel | keyboardFirst user interaction
errorcodeLoad/fullscreen failures
fullscreenChangedfullscreen (boolean)Fullscreen toggled
resizewidth, heightSize changed

Viewer error codes: viewer_unavailable, viewer_load_failed, panorama_load_failed, fullscreen_unavailable.

Creator (public contract)

Creator → Parent: creator:ready-for-init, creator:ready, creator:saved (category: experience | panorama | panorama-order | starting-view), creator:dirty (hasUnpublishedChanges, publicationStatus, draftRevision), creator:published (publicId, liveUrl, revisionNumber, sourceDraftRevision), creator:unpublished, creator:error (category, message), creator:reauth-required.

Parent → Creator: creator:init with { "token": "<creator-session-token>" } (exactly those envelope keys plus token).

Internal Creator React events are not a partner contract.

Minimal parent snippet

html
<script>
  const CREATOR_ORIGIN = "https://YOUR_ARCHWALK_APP_HOST";
  const iframe = document.getElementById("creator");
  const sessionToken = "<creator-session-token>"; // CREATOR_SESSION_TOKEN from your backend, never the API key

  window.addEventListener("message", (event) => {
    if (event.origin !== CREATOR_ORIGIN) return;
    if (event.source !== iframe.contentWindow) return;
    const data = event.data;
    if (!data || data.source !== "archwalk360" || data.version !== 1) return;
    if (data.type === "creator:ready-for-init") {
      iframe.contentWindow.postMessage(
        { source: "archwalk360", version: 1, type: "creator:init", token: sessionToken },
        CREATOR_ORIGIN
      );
    }
  });
</script>

PreviousPartner integration
NextMedia