Hosted handoff first success
Use this path to prove the smallest Fabu-compatible integration before configuring webhooks, Finance, or production. You will install the verified SDK-backed reference, fetch the synthetic catalog, and create one identity-free 15-minute browser handoff.
This is a technical first-success path, not go-live certification. Current v2 access still comes from Chia's signed onboarding package. Self-service synthetic workspaces are planned and are not claimed to exist in this release. Existing pinned v2 sandbox handoffs open the documented isolated tracker-free page and never create a patient, charge, prescription, or fulfillment.
What you need#
From the verified integration bundle and its signed onboarding receipt:
- Bun 1.3.11,
curl,jq, and Python 3; - the exact sandbox API, asset, and care origins;
- the sandbox runtime credential only.
You do not need a webhook endpoint, Finance credential, custom domain, production credential, or patient-data permission for this first result. They remain part of the applicable one-hour integration and go-live checklist.
1. Verify the bundle and install the reference#
From the extracted bundle root, verify the closed file set and machine contracts:
python3 scripts/partner_contracts/verify_integration_bundle.py .
python3 scripts/partner_contracts/check_compatibility.py \
--validate-all --output json
python3 scripts/partner_contracts/check_renderer_conformance.py
Install the reference backend's locked dependency graph. In the delivered bundle its lockfile points to the exact verified SDK tarball under sdk/; it does not use Chia source or a registry substitute.
cd examples/partner-reference-backend
bun install --frozen-lockfile --ignore-scripts
Checkpoint: installation succeeds without running package lifecycle scripts, and node_modules/@chiahealth/partner resolves to the bundle's exact SDK release.
2. Configure only the runtime workload#
cp .env.serve.example .env.serve
chmod 600 .env.serve
Fill only these values from sandbox onboarding:
CHIA_ENVIRONMENT=sandbox
CHIA_API_ORIGIN=<exact sandbox API origin>
CHIA_ASSET_ORIGIN=<exact sandbox asset origin>
CHIA_CARE_ORIGIN=<exact sandbox care origin>
CHIA_RUNTIME_KEY=<sandbox runtime credential>
Keep .env.serve out of source control, support messages, screenshots, logs, and mobile builds. A deployed service should receive the value from its approved secret manager.
Start the reference with an empty inherited environment:
env -i PATH="$PATH" sh -c 'set -a; . ./.env.serve; set +a; bun run start'
The server fetches the catalog on its backend schedule, verifies and mirrors authenticated assets, and publishes only a mobile-safe local projection.
With the sandbox reference running, open http://localhost:8787/demo. This is the official no-tracking web renderer: it displays the complete release in the required order, refreshes the local decision at the program tap and after a browser restore, presents the supplied share and no-share actions with equal access, and prevents duplicate session creation. The browser receives no Chia credential or authenticated asset URL. The route is unavailable when the reference runs in production mode.
3. Fetch one eligible synthetic listing#
In another terminal, keep one fresh partner-owned service-state observation for both the listing read and the handoff action:
cd examples/partner-reference-backend
mkdir -p .state
chmod 700 .state
observed_at="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
curl --fail-with-body --silent --show-error \
-H 'X-Demo-Service-State: AZ' \
-H "X-Demo-State-Observed-At: $observed_at" \
http://localhost:8787/catalog > .state/first-catalog.json
jq '{object, items: [.data[] | {id, title: .presentation.title, handoff: .handoff.mode}]}' \
.state/first-catalog.json
The selected fixture must report share_or_neutral. The real partner implementation derives state from its authenticated account and never forwards a user, account, device, contact, or service-state identifier to Chia.
4. Create one consented handoff#
This command models the affirmative action after the exact catalog disclosure is visible. It stores the operation key so an uncertain retry reuses the same UUID and byte-identical body.
item_id="$(jq -er '.data[] | select(.handoff.mode == "share_or_neutral") | .id' \
.state/first-catalog.json | head -n 1)"
disclosure_version="$(jq -er \
'.data[] | select(.id == $id) | .handoff.primary.disclosureVersion' \
--arg id "$item_id" .state/first-catalog.json)"
python3 - <<'PY'
from pathlib import Path
from uuid import uuid4
path = Path('.state/first-handoff-idempotency-key')
if not path.exists():
path.write_text(f'{uuid4()}\n', encoding='ascii')
path.chmod(0o600)
PY
idempotency_key="$(cat .state/first-handoff-idempotency-key)"
affirmed_at="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
jq -n \
--arg item "$item_id" \
--arg disclosure "$disclosure_version" \
--arg affirmed "$affirmed_at" \
'{catalog_item_id:$item,disclosure_version:$disclosure,consent_attestation:{affirmed:true,affirmed_at:$affirmed}}' \
> .state/first-handoff-request.json
curl --fail-with-body --silent --show-error \
-X POST http://localhost:8787/handoff-session \
-H 'Content-Type: application/json' \
-H "Idempotency-Key: $idempotency_key" \
-H 'X-Demo-Service-State: AZ' \
-H "X-Demo-State-Observed-At: $observed_at" \
--data-binary @.state/first-handoff-request.json | \
python3 -c '
import json, sys, webbrowser
response = json.load(sys.stdin)
url = response.get("url")
expires_at = response.get("expires_at")
if not isinstance(url, str) or not isinstance(expires_at, str):
raise SystemExit("handoff response is invalid")
if not webbrowser.open_new(url):
raise SystemExit("system browser could not be opened")
print(json.dumps({"created": True, "expires_at": expires_at}))
'
Checkpoint: the system browser opens and the terminal reports created: true with an expiry 15 minutes after creation. The response has only url and expires_at; the consumer passes the URL directly from memory and never prints or writes it. Treat browser return as navigation only, never evidence of purchase or clinical approval.
The /demo page exercises this same session endpoint without printing or persisting its short-lived result. Use the command path for transport inspection and the renderer for visual, keyboard, screen-reader, mobile, background/restore, and double-tap verification.
The v2 sandbox destination is the existing isolated synthetic page. The additive complete-care scenario workspace described in the platform plan is not part of this release.
Next steps#
- Use Catalog, assets, and handoff to replace demo state headers with authenticated partner-account evidence and wire the mobile system-browser action.
- Continue the one-hour integration for role separation, webhook certification, Finance fixtures, and the complete current v2 acceptance sequence.
- Use Errors, retries, and idempotency to handle revoked credentials, stale publications, expiry, network uncertainty, rate limits, and idempotency conflicts.
- Complete Go live only after the exact production release, agreement, clinical/commercial review, credentials, endpoints, and signed activation receipt are ready.