# return.purified.app > Helper mini-apps: open with returnUrl, user captures one thing, redirect back with value+format. Canonical human docs: https://github.com/purified-app/return-apps/blob/main/docs/integration.md Contract: https://github.com/purified-app/return-apps/blob/main/docs/contract-v1.md Hub: https://return.purified.app/ Developers: https://return.purified.app/developers/ Catalog JSON: https://return.purified.app/apps.json SDK: https://return.purified.app/sdk/return-apps.mjs ## Critical rules for agents 1. Success params are always `value` and `format` (plus optional `state`). Cancel: `error=cancelled`. 2. Apps `pin` and `sign` default to delivery=hash — parse `location.hash` (or use SDK `parseReturnResult`). QR with `output=png` also defaults to hash. 3. Always pass `allowedOrigins=` with `returnUrl`. 4. Base: `https://return.purified.app//` with query string open params. 5. Prefer SDK: ```js import { openReturnApp, parseReturnResult } from 'https://return.purified.app/sdk/return-apps.mjs'; location.href = openReturnApp('pin', { returnUrl: location.href, allowedOrigins: [location.origin], state: 'x' }); const { value, format, error } = parseReturnResult(location); ``` ## Apps - sign — /sign/ — hash — format=sign.svg — value=SVG data URL - scan — /scan/ — query — format=scan.* — value=payload — open: formats?,batch? — batch returns format=scan.batch + count - geo — /geo/ — query — format=geo.point — value=lat,lng — extras: lat,lng,accuracy,timestamp,label?,… — open: highAccuracy? - map — /map/ — query — format=map.point|map.distance|map.area — value=lat,lng or meters or m² — extras: lat,lng,zoom or meters,points,… — open: lat,lng,zoom?,mode?,units? - pin — /pin/ — hash — format=pin.digits — value=digits — open: length?,mask? - nfc — /nfc/ — query — format=nfc.* — value=payload — extras: recordType — open: mode?,text? — Chrome/Android HTTPS - color — /color/ — query — format=color.hex — value=#rrggbb — extras: rgb — open: mode?,hex? - level — /level/ — query — format=level.level|level.incline — value=pitch,roll or incline° — open: mode?,threshold?,requireLevel? — extras: mode,heading?,pitch?,roll?,incline?,withinThreshold?,deviation?,tare? — tool: Hold/Copy/Tare - qr — /qr/ — query (hash if output=png) — format=qr.svg\|qr.png — value=SVG or PNG data URL — open: text?,output?,auto? - compass — /compass/ — query — format=compass.heading — value=heading° — extras: mode,heading? — tool: Hold/Copy - orient is an alias of level (`openReturnApp('orient')` → `/level/`; old `orient.*` formats are now `level.*`). `mode=compass` on Level redirects to Compass. ## Do not - Do not use legacy keys pin/signature/scanValue/nfcValue/hex as primary return fields - Do not assume postMessage delivery - Do not skip hash parsing for pin/sign (or qr when output=png)