Can a Web Page Send a Custom `deeplink_message`? – Quest Deep-Link Observations
TL;DR
I can launch my Quest 3 app from the browser with destination_api_name=delete_circle_new, but deeplink_message is ignored — the app always receives the literal message string set in the Meta dashboard. I’d love to know if runtime substitution is supported (and if so, what I’m missing).
Use-case
App: ArcGlyph – single-player MR sandbox where users place “circles” (anchors).
Desired flow: On the companion web page I list a user’s circles. Next to each one is Delete → clicking it should:
Launch (or foreground) ArcGlyph,
Pass the specific circle ID in deeplink_message,
Inside OnDeeplinkReceived() I call DeleteCircle(id) and show toast confirmation.
Everything is local-only: no friend invites, no social flow, no server-side state change.
Timeline of what we actually tried
1 | Static oculus:// URI in Quest Browser: oculus://{app_id}?deeplink_message=42 | Opens my store listing; OnDeeplinkReceived() never fires. |
2 | Template-based deep links (/{app-id}/custom_update with type DEEPLINK) | API insists on template_id; seems scoped to social milestones, so not viable here. |
3 | Legacy “poly-deeplink” endpoint (curl sample from old docs) | Returns 410 Gone. |
4 | Graph API → /{app-id}/app_deeplink_public from a Cloudflare Worker (server-to-server, app token) | ✔ Launches the app every time. ✘ deeplink_message never substituted; app receives the exact default string from the Destination config page. |
5 | Same call but moving payload into url param (e.g. ?c=42) | Works, but Quest shell opens the Browser instead of routing into ArcGlyph. |
6 | Verified dashboard settings – Destination set to delete_circle_new, default message “TEST”, deeplink_message checkbox ticked (doc says message should be replaced by API param). | Still get “TEST” inside the app even when POST body passes deeplink_message=xyz. |
Code that currently “works” (opens app, no substitution)
const body = new URLSearchParams({
destination_api_name: 'delete_circle_new',
fields: 'url',
access_token: `OC|${APP_ID}|${APP_SECRET}`,
deeplink_message: id // <— ignored
});
fetch(`https://graph.oculus.com/${APP_ID}/app_deeplink_public`, { method:'POST', body });
Observations & Open Questions
Feature access is confirmed – The dashboard now shows Deep Links enabled; no API errors.
Dashboard default overrides param – deeplink_message in POST body appears to be ignored. Is that by design?
Payload limit unclear – Docs mention 64-byte limit, but since substitution never happens I can’t test the ceiling.
- No social context – Because the flow is single-player, using social templates feels like the wrong hammer.
What I’m hoping to clarify
Is runtime deeplink_message substitution supported for calls to app_deeplink_public?
If yes: any example of a request/response pair that actually overrides the dashboard text would be gold.If substitution is intentionally disabled, what’s the recommended pattern for passing a small (≤ 64 B) opaque string from browser → Quest app?
Is the 64-byte cap fixed? A doc footnote on exact size (and whether it’s bytes or UTF-8 chars) would help future devs plan.
Thanks for any insight, and for maintaining the deep-link feature — when it fires, the UX is fantastic!