Skip to main content

Overview

Config Bundles are versioned JSON payloads that contain all the configuration the SDK needs to render onboarding flows, paywalls, feature flags, remote config, and in-app messages. The SDK downloads the bundle at launch and caches it locally, polling for updates periodically.

Endpoints

Download Latest Bundle

GET /api/v1/sdk/config-bundle
Authentication: SDK Key (x-api-key header) Returns the full config bundle including all content. Use this when the SDK needs the complete configuration. 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": { ... }
  }
}

Check Bundle Version

GET /api/v1/sdk/config-bundle/version
Authentication: SDK Key (x-api-key header) Lightweight version check that returns metadata without the full content payload. Use this for polling. 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 frequent polling without unnecessary bandwidth usage.

Force Regenerate Bundle

POST /api/v1/sdk/config-bundle/generate
Authentication: Customer JWT (Authorization: Bearer header) Forces the server to regenerate the config bundle. Returns the newly generated bundle. Use this after making configuration changes that you want to push immediately. Response: Same shape as the Download endpoint.

Bundle Version History

GET /api/v1/sdk/config-bundle/history
Authentication: Customer JWT (Authorization: Bearer header) Returns a paginated list of previous bundle versions. Query parameters:
ParameterTypeDefaultDescription
limitnumber20Number of versions to return (max 100)
offsetnumber0Pagination offset

SDK Bootstrap

GET /api/v1/sdk/bootstrap
Authentication: SDK Key (x-api-key header) Returns the minimal information the SDK needs to initialize. Response:
{
  "orgId": "org-abc123",
  "appId": "app-def456",
  "firestorePath": "orgs/org-abc123/apps/app-def456"
}

Bundle Content Schema

The content field of the config bundle contains all published configurations organized by type:
{
  "content": {
    "onboarding_flows": {
      "<flow_id>": {
        "id": "flow-abc",
        "name": "Welcome Flow",
        "steps": [ ... ],
        "settings": { ... },
        "published_at": "2026-02-19T09:00:00Z"
      }
    },
    "paywalls": {
      "<paywall_id>": {
        "id": "pw-def",
        "name": "Premium Upgrade",
        "layout": "vertical",
        "plans": [ ... ],
        "cta": "Start Free Trial",
        "dismiss": true,
        "published_at": "2026-02-19T09:00:00Z"
      }
    },
    "remote_config": {},
    "feature_flags": {},
    "in_app_messages": {
      "<message_id>": {
        "id": "msg-ghi",
        "name": "Feature Announcement",
        "message_type": "modal",
        "content": { ... },
        "trigger_rules": { ... },
        "audience": { ... },
        "priority": 10
      }
    }
  }
}

Content Types

KeyDescription
onboarding_flowsStep-by-step onboarding sequences with UI configuration
paywallsPaywall layouts, plans, and CTA configuration
remote_configKey-value remote configuration pairs
feature_flagsBoolean feature flag definitions with targeting rules
in_app_messagesTriggered in-app messages with audience targeting

SDK Polling Pattern

The recommended SDK integration pattern minimizes bandwidth while keeping configuration fresh:
1. App launch  -->  GET /config-bundle  (full download)
2. Cache locally
3. Every N minutes  -->  GET /config-bundle/version  (lightweight check)
4. If bundle_version > cached version  -->  GET /config-bundle  (full download)
5. Update local cache
// AppDNA SDK handles this automatically
let config = AppDNA.shared.configure(apiKey: "adn_live_pk_xxx")

// The SDK polls for updates and caches the bundle locally.
// Access config values synchronously after initialization:
let flow = AppDNA.shared.onboardingFlow(id: "welcome")

Auto-Generation

The config bundle is automatically regenerated when any of the following actions occur in the dashboard:
  • An onboarding flow is published or unpublished
  • A paywall is published or updated
  • An in-app message is published or updated
  • Remote config or feature flags are modified
Manual regeneration via POST /config-bundle/generate is available but rarely needed. The platform handles regeneration automatically on publish.

CI/CD Integration

For zero-latency first launch, download the config bundle at build time and embed it as a fallback:
# Download the latest bundle during your CI build
curl -s https://api.appdna.ai/api/v1/sdk/config-bundle \
  -H "x-api-key: $APPDNA_SDK_KEY" \
  -o appdna-config.json

# Include appdna-config.json in your app bundle
# The SDK will use this as a fallback if the network request fails on first launch
The embedded bundle is a fallback only. The SDK will always attempt to fetch the latest bundle from the server on launch. Ensure your CI pipeline runs frequently enough that the embedded bundle does not become stale.
Your config bundle integration is working correctly when the SDK logs ConfigBundle loaded (version: N) during initialization and you see your published onboarding flows or paywalls rendering on device.