Skip to content

License keys

BGeo verifies license keys offline — no device ever calls a license server. A key is an Ed25519-signed token bound to your app, read from the platform manifest at launch, before any Dart runs.

Evaluation

Debuggable builds and the iOS simulator run without a key. You can integrate and test the full SDK before buying anything.

Adding the key

The key lives in the app manifest — the same mechanism for React Native, native, and Flutter apps — read at launch before any Dart runs. There is no Config option; one license covers your app regardless of how it’s built, because it is bound to your app identity, not to a framework.

Androidandroid/app/src/main/AndroidManifest.xml:

<application>
<meta-data
android:name="com.bgeo.license"
android:value="BGEO1....YOUR_KEY" />
</application>

iOSios/Runner/Info.plist:

<key>BGeoLicense</key>
<string>BGEO1....YOUR_KEY</string>

Production keys are bound to your app

A production key is required for release builds and is bound to your app:

  • AndroidapplicationId + the SHA-256 of your app-signing certificate. Register your Play App Signing certificate (not just the upload key).
  • iOS — bundle id + Team ID.

A key issued for one app identity will not validate in a different one, even with an otherwise-valid, unexpired token.

Build-date gating: shipped apps never brick

A key is a perpetual license with one year of updates, not a subscription that can lock users out of an app they’ve already installed. BGeo enforces this with build-date gating: a production key is valid as long as its expiry is on or after the date the SDK build was released. The device’s wall clock is never consulted for this check, so there is nothing on the device to tamper with and nothing that can brick a shipped app.

Concretely:

  • An app built with an SDK version released during your license term keeps working forever, for every end user, entirely offline — renewing or not renewing has no effect on it after you’ve shipped.
  • Expiry only affects future SDK upgrades: if you want to update the dependency to an SDK version released after your key expired, you need a renewed key first. Renewal is purchased per license pack on the bgeo.dev dashboard.
flowchart LR
    A[Buy a license] --> B["Expiry date set\n(1 year of updates)"]
    B --> C{SDK build's release date<br/>vs. key expiry}
    C -->|"on or before expiry"| D["ready()/start() succeed\nkeeps working forever, offline"]
    C -->|"after expiry"| E["ready()/start() reject\nLICENSE_EXPIRED"]
    E --> F[Renew the pack on bgeo.dev]
    F --> G[Unlocks SDK versions\nreleased after the old expiry]

Error codes

In a release build, an invalid key makes ready() and start() reject with one of these PlatformException codes (see the full License codes reference):

CodeMeaning
LICENSE_MISSINGNo key in a release build
LICENSE_INVALIDBad signature or malformed token
LICENSE_EXPIREDKey expired before this SDK build
LICENSE_APP_MISMATCHKey not bound to this app id / cert / Team ID
try {
await bg.BackgroundGeolocation.ready(bg.Config(/* … */));
} on PlatformException catch (e) {
if (e.code.startsWith('LICENSE_')) { /* surface to the user */ }
}

Debug builds never produce these codes — they run unlicensed regardless of key state.

Buying and managing keys

License keys are purchased and managed from the bgeo.dev dashboard: buy a new key for an app identity, renew an existing pack before it expires, or look up which SDK versions a given key currently covers.

The bgeo.dev dashboard's license page for an app: the updates-until date, regenerations left, the license key with a copy button, the renew action, and the app-identifier fields with a Re-issue key button.

Anti-tamper, honestly

The gate stops honest-but-unlicensed use and casual copying. Like every offline-licensed SDK, a determined attacker can patch the binary. We don’t pretend otherwise — the value is the SDK, the updates, and the support.