Skip to content

Last updated: 2026-10-09

Shipping an Even Hub app comes down to three things: moving a build through the tags in the Builds tab, clearing a manual review against a fixed checklist, and accepting that published versions are immutable. Process first, then the reviewer rubric, then release notes.

For the manifest schema and the .ehpk itself, see Packaging & Deployment.

Don't commit your API key

Never bundle secrets or API keys into the .ehpk. Once a build is published, anyone can extract its contents. Move third-party keys behind a server-side proxy you control, and read environment-driven values into the bundle at build time only. This applies to every API key - third-party AI services, analytics, maps, anything.

The state machine ​

Every build in the Builds tab carries one tag, and that tag is the control: clicking it is how the build changes state. Three tags, and once a version enters review the tag is replaced by the review status and stops being clickable.

TagSection it sits inWho can install it
PrivatePrivate buildsYou, from the phone app's developer section. Metadata still editable.
BetaBeta buildEvery Active tester on the app's list. One beta slot per app.
PublicPublic buildEveryone, from the store, once the version is published.
Review statusSet byWhat it means
In ReviewYou, by submittingThe build is in the reviewer queue. The tag locks. Cancel review in the build's detail modal pulls it back out.
ApprovedEven Realities reviewerCleared review.
RejectedEven Realities reviewerFix and submit a higher version - see Fix-forward versioning.
PublishedEven RealitiesLive in the store, listed under Public build. No rollback - any change requires publishing a higher version.

What each transition actually is in the portal:

FromWhat you clickResultIn the terminal
nothingUpload .ehpk in the Builds tabBuild appears under Private builds, tagged Privateevenhub upload
PrivateThe tag → Beta → Promote to BetaBuild moves to Beta build, installable by Active testersevenhub promote <version> --to beta
Private or BetaThe tag → Public → Submit this build for review? → ConfirmStatus becomes In ReviewPortal only
Beta or PublicThe tag → Private → Delist this project from Even Hub?Build drops back to Private buildsevenhub delist --from beta or --from public
In ReviewCancel review in the build's detail modalReview withdrawn, the tag is clickable againPortal only

Upload, promote and delist run from either side. Submitting for review, publishing to the store, cancelling a review and editing the listing of an app that is already published happen in the portal. See CLI.

Confirm stays disabled until the store listing is complete - developer information, product screenshots, permission information, and the app icon. The same dialog carries an Edit listing shortcut to fill in whatever is missing.

Fix-forward versioning ​

Once a version is Published, that version number is permanent. You cannot:

  • Edit the manifest of a published build
  • Replace the .ehpk of a published version
  • Roll back to an earlier published version

You can only publish a higher version that supersedes it. Plan accordingly:

  • Bug-fix or hotfix? Publish 0.1.1 to supersede 0.1.0.
  • Breaking change? Bump min_sdk_version so users on older firmware stay on the previous version.
  • Shipped a mistake? A published version stays published. Publish a higher version that no-ops the broken behavior.

Reviewer flow ​

Once a build's status reads In Review:

  1. Reviewer assignment - automated.
  2. Reviewer install - the reviewer installs the build as a beta tester (the same path you use for Beta Testing).
  3. Reviewer test - the rubric below.
  4. Reviewer decision - Approved or Rejected, rejections carrying notes.
  5. Notifications - both decisions email you (see Email notifications) and post to the dev portal inbox.

Email notifications ​

Every review decision triggers an email to your developer account address:

  • Sender: noreply@evenrealities.com - add it to your contacts so decisions don't land in spam. Replies go to shawn.deng@evenrealities.com if you have questions.
  • Subject: You have an update on your Even Hub App Submission - the subject is fixed and identical for approvals and rejections.
  • Only decisions trigger email. Approved and Rejected each send one; submitting a build for review does not.
  • The email doesn't carry the outcome. It's a nudge with a link - open the dev portal to see the decision and, for rejections, the reviewer notes.

What reviewers check ​

The reviewer's job is to confirm your build behaves like a real shipped app. The full rubric:

Manifest (app.json) ​

  • package_id - reverse-domain, lowercase, no hyphens, no underscores, ≥ 2 segments. Every segment must start with a lowercase letter (e.g. com.acme.weather).
  • edition - exactly "202601" (current edition as of 2026-04-22).
  • name - ≤ 20 characters and must not contain "Even" (case-insensitive). Names like "EvenDoc Reader" or "Even Bible" are auto-rejected as first-party impersonation. Exception: officially affiliated apps with written approval.
  • version - three-part semver x.y.z. No v prefix, no pre-release suffix.
  • min_sdk_version - required. Current SDK floor: "0.0.14".
  • min_app_version - optional in your source app.json since CLI 0.1.14 - the CLI derives it from your SDK version and stamps it into the packed manifest, so the reviewer always sees it filled. Declare it yourself only to pin a stricter floor. See Auto-deriving min_app_version.
  • entrypoint - must resolve to a real file inside the build output folder.
  • permissions - array of objects with name + desc (1–300 chars). network entries also need whitelist. Not a key-value map.
  • Every requested permission must actually be used in app code. Unused permissions are flagged. Common mappings: location for any getAppLocation / startAppLocationUpdates call, album for pickImageFromAlbum, camera for captureImageFromCamera, g2-microphone for audioControl(true, AudioInputSource.Glasses), phone-microphone for audioControl(true, AudioInputSource.Phone).
  • New version submissions need a non-empty changelog.

See Packaging & Deployment → Field Reference for the underlying schema.

Store listing & visual assets ​

  • Icon is legible - no "black scribble" or noisy patterns.
  • Both foreground and background are supplied (neither null nor empty).
  • Icon and background image are monochrome / greyscale only. Color assets are rejected.
  • Screenshots match what the app actually renders on device - capture them via the simulator's screenshot function.
  • Display name matches app.json name and the on-glasses display name (no portal-vs-device mismatch).
  • No impersonation of existing apps, no unauthorized brand logos, no keyword stuffing in name/description.

Privacy ​

  • Privacy policy covers every permission the app requests.
  • Backend service domains, if any, are documented and traceable to the developer.

First-run experience (no black screens) ​

  • First launch from glasses when setup is needed (city, API key, player name, …) → on-glasses message explains what to do. Never a black screen.
  • Setup is remembered across launches (use the localStorage API) - never re-prompt the same setup.
  • CORS headers correctly configured on any third-party API the app calls. The app.json network whitelist is an Even-side permission check - it is not a CORS bypass. If a request works locally but fails inside the WebView, the remote API is misconfigured for CORS, not an Even bug.

Locked-phone operation ​

The Even G2 is designed to be useful with the phone in your pocket. Reviewers specifically test with the phone locked and the Even Realities App backgrounded.

Test in the right mode. Reviewers run a beta build via Beta Testing, which survives a locked phone. Local Testing (QR sideload) dies when the WebView backgrounds, so it cannot validate the checks below - reproduce them with a beta build before submitting. The behaviour these checks probe is explained in Background & Lifecycle.

  • Phone locked + Even App backgrounded → glasses-launched app renders within reasonable time. No infinite spinner, no black screen.
  • Phone locked → the core flow runs end-to-end on glasses + ring input alone. Every gesture has a visible response, every button has feedback, every image loads.
  • Long-running single-shot tasks (Timer, etc.) continue and complete correctly while the phone stays locked.
  • After 2 minutes idle the app is still alive and responsive. No freeze, no infinite loop, no crash.
  • Unlock → use another phone app → re-lock - the glasses session is unaffected.

Exit & lifecycle ​

  • Root-page double-tap calls bridge.shutDownPageContainer(1) - the system exit confirmation dialog. Mode 0 (immediate exit) is not acceptable on the root page. A custom in-app exit confirmation UI is not acceptable on the root page either. Apps that exit silently or do nothing on double-tap are rejected.
    • Reference patterns:
      • Make15 - root double-tap fires the system dialog directly.
      • Chess - root double-tap opens an in-app menu containing an "Exit" item that then calls shutDownPageContainer(1).
  • After the user confirms exit on glasses, the phone-side WebView page also closes automatically. Lingering webviews inside the Even Realities App are rejected.
  • After exit, glasses can launch other apps and first-party apps (Conversate, Navigate) without restart. Smoke-testing with Conversate alone is sufficient.

See Page Lifecycle for page-creation and exit patterns.

Content & safety ​

  • No medical diagnosis, financial advice, or emergency-routing functionality. Flag for legal if unavoidable.
  • No offensive, explicit, NSFW, or hateful content.

Release notes ​

When you submit for review you provide release notes for each supported_language. Conventions:

  • Length - 1-3 lines per locale. Reviewers and users both skim.
  • Tone - what changed for the user, not what changed in the code.
  • First version - describe what the app does, not "initial release."
  • Hotfixes - name the symptom, not the commit message ("Fix occasional blank screen after returning from lock" not "fix race in onResume").

Final pre-submission sanity check ​

Before clicking Submit, run through this short loop:

  1. evenhub pack app.json dist -o myapp.ehpk -c - confirm package_id is available and the manifest validates.
  2. Install as a beta build via Beta Testing and lock the phone for 5 minutes - does the app stay alive and responsive? (Local Testing / QR sideload dies on background and will give a false failure here.)
  3. Trigger a root-page double-tap - does the system exit dialog appear and the WebView close?
  4. Re-launch a first-party app (Conversate) - does it start without restarting glasses?
  5. Re-read your privacy policy - does it cover every permission in app.json?

If all five pass, you are ready to submit.

Common confusions ​

QuestionAnswer
"Why is my reviewer install showing old code?"Reviewers install the version whose status reads In Review. Anything you changed since sits in a newer Private build - submit that one instead.
"Can I take a published version back to testing?"No. Published is terminal for that version number. Publish a higher version.
"My build came back as Rejected. What now?"The reviewer left notes. Read them, fix, then submit a higher version for review.
"How do I withdraw a build that is In Review?"Open the build in the Builds tab and click Cancel review. The tag becomes clickable again.
"Why isn't my user seeing the new version?"Their firmware likely sits below the new min_sdk_version. They need a firmware update before they're eligible.