Skip to main content

Config Bundles in CI/CD

A config bundle is a versioned JSON snapshot that contains everything the SDK needs to run without a network connection: onboarding flows, paywalls, in-app messages, feature flags, experiment definitions, and remote config values. By embedding a config bundle in your app binary during CI/CD, you guarantee a fully configured experience on first launch — even if the user has no internet connection.

What is a Config Bundle?

The config bundle is a single JSON file generated server-side whenever you publish changes in the dashboard. It contains:
SectionDescription
onboarding_flowsStep-by-step onboarding sequences with UI configuration
paywallsPaywall layouts, pricing plans, and CTA configuration
in_app_messagesTriggered messages with audience targeting and display rules
feature_flagsBoolean feature flag definitions with targeting rules
remote_configKey-value configuration pairs
experimentsExperiment definitions with variant allocations and salts
Each bundle includes a bundle_version number that increments on every generation, along with metadata like generated_at and sdk_min_version.

API Endpoints

Download Current Bundle

GET /api/v1/sdk/config-bundle
Authentication: SDK API key via x-api-key header. Returns the full config bundle including all content. This is the endpoint you call in your CI/CD pipeline.
curl -s https://api.appdna.ai/api/v1/sdk/config-bundle \
  -H "x-api-key: $APPDNA_SDK_KEY" \
  -o appdna-config.json
Response:
{
  "bundle_version": 42,
  "sdk_min_version": "1.0.0",
  "size_bytes": 15234,
  "generated_at": "2026-02-19T10:00:00Z",
  "content": {
    "onboarding_flows": { ... },
    "paywalls": { ... },
    "remote_config": { ... },
    "feature_flags": { ... },
    "in_app_messages": { ... },
    "experiments": { ... }
  }
}

Check Bundle Version

GET /api/v1/sdk/config-bundle/version
Authentication: SDK API key via x-api-key header. Lightweight version check that returns metadata without the full content payload. Useful for polling or conditional downloads in CI.
curl -s https://api.appdna.ai/api/v1/sdk/config-bundle/version \
  -H "x-api-key: $APPDNA_SDK_KEY"
Response:
{
  "bundle_version": 42,
  "sdk_min_version": "1.0.0",
  "generated_at": "2026-02-19T10:00:00Z"
}
This endpoint returns only metadata (no content field), making it ideal for checking whether you need to download a new bundle before every build.

Force Regenerate Bundle

POST /api/v1/sdk/config-bundle/generate
Authentication: Dashboard API key via Authorization: Bearer header. Forces the server to regenerate the config bundle from the current published state of all modules. Returns the newly generated bundle.
The platform automatically regenerates the bundle whenever you publish changes in the dashboard. Manual regeneration is rarely needed but can be useful in CI/CD pipelines that need to ensure the bundle reflects the very latest state.

Bundle Version History

GET /api/v1/sdk/config-bundle/history
Authentication: Dashboard API key via Authorization: Bearer header. Returns a paginated list of previous bundle versions with metadata. Useful for auditing or rollback workflows.
ParameterTypeDefaultDescription
limitnumber20Number of versions to return (max 100)
offsetnumber0Pagination offset

CI/CD Integration

Adding a config bundle download step to your build pipeline takes three steps:
1

Add a build step that downloads the bundle

Call GET /api/v1/sdk/config-bundle with your SDK API key and save the response to a JSON file.
2

Save the file to the platform-specific assets directory

Each platform expects the file in a specific location (see platform-specific examples below).
3

Build your app as normal

The SDK automatically detects the bundled config file and uses it as the last-resort fallback when no remote or cached config is available.

Build Script Examples

Add a lane or a pre-build action to your Fastfile:
desc "Download AppDNA config bundle"
lane :download_appdna_config do
  sh(
    "curl -s " \
    "-H 'x-api-key: #{ENV['APPDNA_SDK_KEY']}' " \
    "https://api.appdna.ai/api/v1/sdk/config-bundle " \
    "-o ../Resources/appdna-config.json"
  )
  UI.success("AppDNA config bundle downloaded")
end

desc "Build the app"
lane :build do
  download_appdna_config
  build_app(scheme: "MyApp")
end
Make sure Resources/appdna-config.json is added to your Xcode project under Build Phases > Copy Bundle Resources.

Version Checking

The SDK automatically compares the local bundled version with the remote version on startup:
  1. On launch, the SDK reads bundle_version from the embedded config file.
  2. It calls GET /api/v1/sdk/config-bundle/version to check the latest server version.
  3. If the server version is newer, the SDK downloads the full bundle and caches it locally.
  4. The bundled version is only used if both the remote fetch and cache miss fail.
The SDK also includes bundle_version in every event it sends. The dashboard warns you if the most commonly reported version is more than 5 versions behind the latest published bundle.
If you see a staleness warning in the dashboard, it means your CI pipeline is not running frequently enough or the config download step is failing silently. Check your build logs and ensure the APPDNA_SDK_KEY environment variable is set.

Best Practices

  1. Regenerate on every deploy. Even if you have not changed any configuration, regenerating ensures the bundle version stays current and the staleness warning stays green.
  2. Use the x-api-key header, not Bearer tokens. The config bundle download endpoint accepts SDK API keys, which are scoped to your app and safe to use in CI environments.
  3. Fail the build if the download fails. Use curl -sf (silent + fail on error) or equivalent so your build breaks visibly if the download fails, rather than shipping an outdated or missing bundle.
  4. Store the API key as a CI secret. Never hardcode APPDNA_SDK_KEY in your build scripts. Use your CI provider’s secret management (GitHub Actions secrets, Bitrise secrets, etc.).
  5. Check the file size. A valid config bundle is always at least a few hundred bytes. If the downloaded file is 0 bytes or suspiciously small, the download likely failed silently.