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 manifest at launch, before any of your code runs.

Evaluation

Debug builds and the Simulator run without a key. You can integrate and test the whole SDK before buying anything.

Adding the key

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

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

Production keys are bound to your app

A production key is bound to your bundle identifier plus your Team ID.

Both are visible in Xcode under Signing & Capabilities. A key issued for one bundle id will not validate in another, and an app distributed under a different team — an agency account, a white-label build — needs its own key. Bundle-id suffixes for build variants (com.example.app.staging) count as different identities.

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 have already installed. 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, 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 user, entirely offline — renewing or not has no effect on it once shipped.
  • Expiry only affects future SDK upgrades: to move to a version released after your key expired, you need a renewed key first.
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() throw\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() throw a BGeoError carrying one of these codes (see License codes):

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 bundle id / Team ID
do {
try await BackgroundGeolocation.ready(config)
} catch let error as BGeoError where error.code.hasPrefix("LICENSE_") {
// Surface it: in a release build this is why nothing is tracking.
}

Debug builds and the Simulator never produce these codes — they run unlicensed whatever the key says.

Buying and managing keys

License keys are purchased and managed from the bgeo.dev dashboard: buy a key for an app identity, renew a pack before it expires, or look up which SDK versions a 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 do not pretend otherwise — the value is the SDK, the updates, and the support.