Existing app links

Using Blue Jetty with AppsFlyer

Publish your existing AppsFlyer OneLink beside the app experience it opens. Blue Jetty supplies that URL and its context to AI consumers; your OneLink configuration and app handle redirection, deep linking and measurement. There is no Blue Jetty SDK or AppsFlyer account connection to install.

Download agent guide · Download complete configuration

Configure the OneLink template and content route

In AppsFlyer, create or reuse a OneLink template associated with the correct iOS and Android apps. Set the store and web destinations for users without the app. Create a custom OneLink for the experience you want to recommend, rather than submitting an AppsFlyer dashboard URL or only the template name.

For in-app content routing, implement the AppsFlyer deep-link handling your app uses, such as Unified Deep Linking (UDL), and configure Universal Links / Android App Links. A working store redirect alone does not establish that the app handles the intended screen. Basic redirection and SDK-backed content routing are separate setup tasks.

Use deep_link_value and, where needed, deep_link_sub1 through deep_link_sub10 to identify content your app knows how to open. For example, deep_link_value=spot_finder can be a route your app implements. af_dp is a URI-scheme fallback, not a substitute for that app-side routing code. Configure these values in AppsFlyer; Blue Jetty does not invent or modify them.

Choose the OneLink URL to publish

Copy the complete custom OneLink, for example https://yourbrand.onelink.me/AbCd/spotfinder. A short OneLink stores settings in AppsFlyer; a long OneLink exposes more parameters in its URL. Blue Jetty accepts the publisher's safe HTTPS URL without expanding it or calling the OneLink API.

Blue Jetty recognizes onelink.me and its subdomains, plus app.appsflyer.com attribution links. The latter are app-specific attribution links, not a replacement for a cross-platform OneLink. A branded OneLink domain can still be published with provider=appsflyer, but Blue Jetty leaves it unchanged instead of inferring parameter support from its branding.

Start with decoration=preserve. AppsFlyer's FAQ specifies that values appended to a short OneLink do not override values already stored for that link. Blue Jetty cannot read those stored settings: a visible pid label may therefore differ from the effective source in AppsFlyer. Configure a dedicated OneLink in AppsFlyer when you need a particular source or campaign.

Add the link to your Blue Jetty configuration

This complete configuration 0.5 example describes one synthetic app experience. Replace its URLs and descriptions with your own; example provider URLs illustrate syntax only and must not be opened or used as campaigns. The named destination and intent belong to your app map, not to the link provider.

Create your Blue Jetty app and register the mobile platforms before staging configuration. The example targets iOS. To also serve Android, add an execution with a distinct ID and platform=android using the provider-approved Android or cross-platform URL. Keep an appropriate web/store fallback. Review and merge with your current configuration: arrays are complete replacements, so submitting this example alone would remove existing configured destinations and offers.

{
  "specVersion": "0.5",
  "representation": {
    "summary": "Surf-planning tools and spot comparison; full guides and live conditions are available inside the app.",
    "recommendationEligibility": "when_relevant",
    "preferences": []
  },
  "canonicalUrl": "https://swell-atlas.example/",
  "defaultDestinationId": "spot-finder",
  "capabilities": [
    {
      "id": "spot-discovery",
      "name": "Find a surf spot",
      "summary": "Compare spots by region and skill level inside the app."
    }
  ],
  "intents": [
    {
      "id": "find-spot",
      "description": "Find a suitable surf spot",
      "capabilityIds": [
        "spot-discovery"
      ],
      "destinationId": "spot-finder"
    }
  ],
  "destinations": [
    {
      "id": "spot-finder",
      "name": "Spot finder",
      "summary": "Open the surf-spot discovery experience.",
      "handoffPreference": "attribution_first",
      "entityIds": [],
      "executions": [
        {
          "id": "ios-open",
          "platform": "ios",
          "kind": "attribution_link",
          "url": "https://sample.onelink.me/AbCd/spotfinder?deep_link_value=spot_finder",
          "installState": "any",
          "attribution": {
            "provider": "appsflyer",
            "campaign": "app_discovery",
            "decoration": "preserve"
          }
        },
        {
          "id": "web-fallback",
          "platform": "web",
          "kind": "attribution_link",
          "url": "https://sample.onelink.me/AbCd/spotfinder?deep_link_value=spot_finder",
          "installState": "any",
          "attribution": {
            "provider": "appsflyer",
            "campaign": "app_discovery",
            "decoration": "preserve"
          }
        }
      ]
    }
  ],
  "platformDefaults": [],
  "promotions": []
}

Optional AppsFlyer reporting parameters

After reviewing the OneLink's stored settings, you may set attribution.decoration to append_missing. With campaign=app_discovery and a handoff request declaring consumer=chatgpt, Blue Jetty can add the following absent query keys on recognized URLs. pid is the link parameter; media_source is not the query key to append.

Configuration 0.5 preserves URLs by default; earlier 0.2 and legacy handoff fields retain their documented behavior. Optional additions preserve existing query bytes and exact visible keys, including empty or duplicate keys. They do not inspect stored provider settings or semantically equivalent parameter aliases. Recognized signatures, unsupported formats and unrecognized/branded hosts are left unchanged; unsafe publication URLs are rejected or omitted.

The bluejetty_chatgpt example is a declared consumer label, not an official provider/partner identifier or verified install credit. Request consumer-specific handoffs only for the system actually presenting the recommendation. Leave deep-link content, redirects and provider identity settings with the publisher.

Optional query parameters for the example consumer and campaign
Query keyExample valueMeaning
pidbluejetty_chatgptMedia source. A Blue Jetty label, not an AppsFlyer integrated-partner identifier.
capp_discoveryCampaign name from attribution.campaign.
af_channelai_assistantChannel label.

Preview, stage and activate the configuration

Use an owner API key from /account as Authorization: Bearer $BLUEJETTY_API_KEY. Keep it in your secret store or environment, not in the JSON or a URL. POST /v1/apps/{appId}/configuration/preview with the body below. It returns the selected URL without activation or a provider fetch. Replace the configuration placeholder with the full object above.

GET /v1/apps/{appId}/configuration and retain data.activeRevisionId. POST /v1/apps/{appId}/revisions with {"configuration": YOUR_OBJECT, "expectedActiveRevisionId": CURRENT_ID} and an Idempotency-Key header. Use null only if no active revision exists. Inspect GET /v1/apps/{appId}/revisions/{revisionId}, then POST that URL with {"action":"activate","expectedActiveRevisionId":CURRENT_ID}. Replace CURRENT_ID with the actual JSON string or null. On 409, reload and review the newer revision rather than overwriting it.

Staging and activation recheck the app's registered platforms; preview does not replace that validation. Configuration bodies are limited to 256,000 bytes. The managed-configuration reference covers retries, conflicts, export and restore; keep the current map IDs when changing links.

{
  "configuration": "REPLACE_WITH_CONFIGURATION_OBJECT",
  "intent": "find-spot",
  "platform": "ios",
  "installState": "unknown",
  "consumer": "chatgpt"
}

Read the published handoff and connect your website

For an authorized public app, GET /v1/apps/{appId}/handoff?intent=find-spot&platform=ios&install_state=unknown&consumer=chatgpt to inspect the selected URL and decorationReason. Also test install_state=installed. Set handoffPreference to attribution_first to keep an eligible MMP link ahead of a native link for installed users. Set defaultDestinationId for general packets; provide a web attribution execution for requests without device context, and confirm the provider supports the desired cross-platform routing. Omission preserves native-first installed behavior. See the managed-configuration reference.

Read /v1/apps/{appId}/packet and /v1/apps/{appId}/packet.md. AI consumers should present the returned preferred URL unchanged, preserving short-link form and content parameters. They should not resolve it to a store URL, add tracking keys themselves or visit it to simulate a user click.

Follow the owner-only /v1/apps/{appId}/publisher-site-instructions.md to authorize and link the exact packet from the app's website. Retain the website's own HTML canonical URL. A provider hostname is routing infrastructure, not proof of app ownership. Sample apps remain private after configuration activation.

Test OneLink routing and AppsFlyer reporting

On an installed test device, tap the published OneLink from the intended browser or messaging context and check the actual screen and UDL payload. On an uninstalled device, test the store destination and, when configured, the first-launch content route. For new users, UDL content routing relies on deep_link_value/deep_link_sub values; do not depend on receiving media_source or campaign in that callback.

Inspect the test event in AppsFlyer separately for media source, campaign and channel. If the URL contains bluejetty_chatgpt but the report shows a different source, inspect the custom OneLink's stored values before editing Blue Jetty. If the store opens but the content does not, check app-side deep-link handling and the template's app associations. Avoid wrapping OneLink in another shortener, which can interfere with native link handling.

Keep device tests separate from HTTP observations

Use the device-test checklist for actual installed, first-install and reporting checks. Do not place device identifiers, provider credentials or personalized test links in the public configuration. Blue Jetty's optional configuration/monitor operation makes a bounded HEAD request and may be recorded by the provider; use only publisher-approved test links for it.

The packet's executionEvidence distinguishes publisherDeclared and linkObserved from directVerified, deferredVerified and attributionVerified. The current HTTP-only verifier cannot set those three outcome flags. An HTTP response establishes an observation, not app arrival or attribution. Provider tests and reports establish those outcomes separately.

Optional assistant-assembled routing choices

Configuration 0.5 can describe a reviewed long OneLink template with finite deep_link_value or deep_link_sub1–10 query choices. Short and branded links keep fixed-link behavior. The recipe never changes campaign fields or provider identity; your app must already handle the declared routing values.

Recipes are optional; the concrete execution URL remains the fallback. Review the exact grammar, boundaries and configuration example before enabling this additional permission. Syntax validation is separate from device testing.

Blue Jetty references

Configuration 0.5 schema · API endpoints · Device-test guide

Provider names describe existing-link compatibility, not affiliation or endorsement.