Using Blue Jetty with Singular
Add an existing Singular Link to the destination it opens in your Blue Jetty app map. Singular and your app continue to handle routing and attribution. Blue Jetty publishes the URL and selection context without creating a Singular Link or accessing your Singular account.
Download agent guide · Download complete configuration
Create a Singular Link with the intended app route
Configure your apps, link domains and platform destinations in Singular, and configure deep-link handling through your Singular SDK or supported S2S integration. For a publisher-managed discovery link, create or reuse a Custom Source link in Manage Links. Choose its source and campaign with the intended iOS, Android and web behavior, then copy the generated link with its provider-assigned path identifiers.
Singular routing fields include _dl for a deep-link target and _ddl for a deferred deep-link target; _p can carry passthrough data for the app. These are publisher/app-specific routing inputs, not campaign labels. Configure and test the payload in Singular and in your app before publishing it through Blue Jetty.
Review the Singular Link's stored settings
Blue Jetty recognizes sng.link and its subdomains. A URL such as https://yourbrand.sng.link/AbCd/efgh contains provider-assigned identifiers; retain them and any deep-link query payload exactly. Custom or branded domains outside sng.link remain unchanged even when provider=singular is declared.
Use decoration=preserve for the initial configuration. A Singular custom short link may have stored parameters and a Disable short link parameters overrides setting. Appended parameters on an unlocked link can override stored values. Blue Jetty does not inspect that configuration, so review it in Singular before opting into append_missing.
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.sng.link/AbCd/efgh?_dl=swellatlas%3A%2F%2Fspots",
"installState": "any",
"attribution": {
"provider": "singular",
"campaign": "app_discovery",
"decoration": "preserve"
}
},
{
"id": "web-fallback",
"platform": "web",
"kind": "attribution_link",
"url": "https://sample.sng.link/AbCd/efgh?_dl=swellatlas%3A%2F%2Fspots",
"installState": "any",
"attribution": {
"provider": "singular",
"campaign": "app_discovery",
"decoration": "preserve"
}
}
]
}
],
"platformDefaults": [],
"promotions": []
}Optional Singular campaign, subcampaign and creative names
With append_missing, campaign=app_discovery and consumer=chatgpt, Blue Jetty can append the following absent keys. The consumer label goes into pscn, a subcampaign dimension. It does not change Singular's configured source or create a partner relationship.
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.
| Query key | Example value | Meaning |
|---|---|---|
pcn | app_discovery | Campaign name. |
pscn | bluejetty_chatgpt | Subcampaign / ad-group name, not source. |
pcrn | app_handoff | Creative name. |
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 Singular deep-link delivery and subcampaign reporting
Tap the published Singular Link on installed and uninstalled test devices. Inspect the app's Singular deep-link callback and the resulting screen, including deferred routing where configured. If the callback arrives but the screen is wrong, inspect the _dl/_ddl target, passthrough data and app handler rather than changing campaign tags.
Inspect source, campaign, subcampaign and creative in Singular reporting as separate dimensions. A bluejetty_chatgpt subcampaign is not a change to the underlying source. If appended labels do not take effect, review parameter locking and the link's stored values before changing the Blue Jetty configuration.
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.
Blue Jetty references
Configuration 0.5 schema · API endpoints · Device-test guide
Provider names describe existing-link compatibility, not affiliation or endorsement.
