i99dash docs
Develop

Beta testing

Publish a build to a small group of Telegram-verified testers before the public catalog. TestFlight-style workflow for i99dash mini-apps.

The CLI ships a beta track for every mini-app. You publish a build to a limited group of testers, iterate based on their feedback, then promote the same bundle to production when you're happy. This is the equivalent of TestFlight for i99dash mini-apps.

GUI equivalent. Every CLI command on this page has a button in the developer portal. Open https://dev.i99dash.app/developers/apps/<your-app-id> and pick the Testing tab — promote / demote, invite testers, view the roster, and graduate to production all live there. The CLI and portal hit the same backend endpoints; pick whichever fits your workflow.

Tester surface on the head unit. Once you accept a beta invite, the build appears on your head unit's Mini Apps screen. Settings → Developer → Flight test mode adds a dedicated third tab listing only the beta builds you're invited to test — see the Flight test guide for the tester checklist.

When to use it

  • You're shipping a behaviour change that's risky on the head-unit (UI rewrite, new bridge feature, backend dependency that just landed).
  • You want a sample of real users to validate before everyone gets it.
  • You need to demo a build to a stakeholder without flipping the production catalog.

If your release is documentation-only or copy-tweaks, skip beta and publish straight to production.

Limits

LimitWhy
25 testers per appIncluding yourself. Backend returns beta.tester_cap_reached (HTTP 422).
90-day beta expiryA beta build expires 90 days after promotion. Promote again or move to production before then.
One beta bundle at a timeThe beta track is a single pointer per app. Promoting a new build replaces the previous one.

Two ways to put a build on the beta track

Path 1 — publish directly to beta

i99dash publish --track beta --release-notes "Rebased on latest map tiles"

Same flow as a regular publish, except the bundle lands on the beta track instead of production. Testers see this build automatically the next time they launch the mini-app.

--release-notes is shown in the consent sheet the host pops up when a tester first opens a new beta build. Keep it short — one sentence is ideal.

Path 2 — publish to production, promote later

i99dash publish                                  # lands on production
i99dash beta promote com.example.myapp 2.0.0 --release-notes "Nightly build"

Use this when:

  • You publish on a CI tag and decide the beta cohort by hand later.
  • You want to roll back the beta to a prior version that's already in the catalog.

Manage the tester roster

Invite a tester

i99dash beta invite com.example.myapp @alice
i99dash beta invite com.example.myapp alice     # @ prefix is optional

The CLI strips a leading @ so you don't have to think about it.

Invite multiple testers in one shot

# Space-separated
i99dash beta invite-batch com.example.myapp alice bob charlie

# Comma-separated (also works)
i99dash beta invite-batch com.example.myapp "alice,bob,charlie"

Use this for the initial roster on a fresh beta — one round-trip instead of N.

List the roster

i99dash beta testers com.example.myapp

Output:

USER ID                              TELEGRAM           STATUS    INVITED AT          ACCEPTED AT
------------------------------------------------------------------------------------------------
01J9VWCB9G…                          @alice             accepted  2026-04-20 14:02 UTC 2026-04-20 14:11 UTC
01J9VWCB9H…                          @bob               invited   2026-04-20 14:02 UTC —

STATUS values:

StatusMeaning
invitedWe've recorded the invite. The user hasn't opened i99dash since the invite, or the username never existed (you can't tell which from this row — see Security below).
acceptedThe user has consented to receive beta builds. They'll see the beta on next launch.
revokedYou removed them via beta revoke. Stays in the table for audit.

Quick status check

i99dash beta status com.example.myapp

One-shot summary — current beta version, days until expiry, tester count vs cap, last publish, release notes. The same numbers render under the Testing tab in the dev portal.

com.example.myapp @ 1.4.2
  status:       ACTIVE (beta-track)
  bundle_sha:   a1b2c3d4e5f6…
  expires:      2026-07-29 (89 days)
  testers:      7 / 25 active
  last_publish: 2026-04-30 14:23 UTC
  release_notes:
    First beta cut

When no beta is active, the command prints a single line:

com.example.myapp — no beta track active.
  last_publish: 2026-04-30 14:23 UTC
  testers:      0 active

Remove a tester

i99dash beta revoke com.example.myapp <user_id>

user_id is the first column of the beta testers table — copy it verbatim. The tester loses access on next launch; their pinned shortcut still works but reverts to the production build.

Promote the beta to production

Two ways:

# Copy the current beta bundle into the production track
i99dash beta promote-production com.example.myapp

This is the fast path when the beta passed review. The current beta bundle becomes the new production version with no rebuild — same SHA-256, same CDN URL, same (id, version) pair.

# Or pull the beta without promoting (e.g. you found a critical bug)
i99dash beta demote com.example.myapp

This clears the beta pointer. Testers fall back to production on next launch.

End-to-end example

Here's the full lifecycle of a single beta cycle:

# Tag a release in CI; it publishes to production on tag push
git tag v2.0.0 && git push --tags

# Decide which version to beta — pick a recent one
i99dash beta promote com.example.myapp 2.0.0 \
  --release-notes "v2: redesigned home, new fuel widget"

# Add your testers
i99dash beta invite-batch com.example.myapp \
  alice bob charlie diana eve

# Watch acceptance over the next day or two
i99dash beta testers com.example.myapp

# After feedback + a fix
git tag v2.0.1 && git push --tags
i99dash beta promote com.example.myapp 2.0.1 \
  --release-notes "v2.0.1: fixes the home-screen tap target"

# Once everyone's happy, ship to production
i99dash beta promote-production com.example.myapp

Security: account enumeration mitigation

The beta invite and beta invite-batch endpoints always return HTTP 200, regardless of whether the supplied Telegram username exists. The CLI prints Invite recorded either way. This is deliberate: a public-facing dev tool that returned different responses for "real account" vs "no such user" would let anyone enumerate i99dash's user base by guessing usernames.

Real status only shows in the beta testers table, which requires your developer login — that gate is what stops enumeration. If you need to confirm an invite landed:

  1. Wait for the user to open i99dash.
  2. Run beta testers <app_id> and look for their row.
  3. If their status is still invited after 24 h, ask them to check the i99dash app's "Mini-apps" tab — there should be a notification.

How a tester actually receives the beta

From the user's side:

  1. Opens i99dash on their car or phone.
  2. Sees a Beta available card on the mini-app the dev invited them to.
  3. Taps the card → consent sheet (with your --release-notes text).
  4. Approves → next launch loads the beta bundle.

The tester can flip back to production at any time from the same card. You don't need to do anything for the rollback path — it's part of the host's beta UX.

Errors

CodeWhenFix
beta.tester_cap_reachedYou hit 25 testers + 1 dev.Revoke someone first, or wait until a tester accepts and replaces a stale invite.
beta.no_active_bundlebeta promote-production ran but no beta bundle exists.Promote a version to beta first.
beta.expiredThe beta has been live for >90 days.Promote a fresh version to refresh the timer.
beta.unknown_appapp_id doesn't exist or you don't own it.Check app_id matches your manifest.json.
beta.tester_not_foundbeta revoke ran with a user_id that isn't on the roster.Run beta testers and copy the user_id verbatim.
  • Publishing — full publish flow, including how --track interacts with the existing pipeline.
  • Authentication — beta commands need the same developer credentials.
  • runPublish reference — programmatic entry point for CI.

On this page