# Desktop cross-promotion networks — a complete guide

> A desktop cross-promotion network lets macOS and Windows apps show each other’s install recommendations and settle at a price per install. This guide covers the data exchanged, integration on each platform, and the alternatives.

Source: https://ghan.io/guides/desktop-cross-promotion-network/  
Published: 2026-09-22 · Updated: 2026-09-22  
Publisher: GHAN — the audited cross-promotion network for desktop apps (https://ghan.io)

---

## What a desktop cross-promotion network is

A desktop cross-promotion network is a system in which independent macOS and Windows applications show each other's install recommendations to their own users, and settle that exchange at a price per install.

Each member is on both sides of the trade. When your app shows another member's card, you are a seller of attention. When another member shows yours, you are a buyer of installs. In the steady state an app that serves as much as it buys never spends cash at all.

This is distinct from three adjacent things:

- **A paid CPI network** buys installs from traffic sources it does not own, usually priced by auction.
- **An app store or curated bundle** is a destination people browse, and it holds the customer relationship.
- **Installer bundling** places offers inside an installer. That is the mechanism that got the previous generation of desktop networks classified as malware, and no current network should be doing it. See [why install networks die](/blog/why-install-networks-die/).

## The full flow, from impression to cleared install

| Stage | What happens | What is exchanged |
|---|---|---|
| Impression | The host app calls a lifecycle slot; the SDK renders a templated card | Partner app id, icon URL, name, one line of copy |
| Click | The person clicks Install | A single-use token: nonce, 15-minute expiry, bound to campaign and serving app |
| Handoff | The partner's download URL opens | Token travels by `ghan://` protocol handler **and** a local handoff file |
| Install claim | The receiving SDK finds the token on first run | Token + the receiving app's own ed25519 signature + VM flags, OS install age, salted hardware hash, clock skew |
| Escrow | Credits move out of the advertiser's balance | Ledger line: `escrow_hold` |
| Clearing (48h) | The receiving SDK confirms the app is still in use | Coarse usage counters — session starts and ends, feature counts |
| Settled | Escrow releases, the serving app earns | Ledger lines: `escrow_release`, `earn` |
| Or rejected | Any check fails | Hold refunded automatically, reason code exposed to both parties |

Nothing personal is exchanged at any stage. The attribution is a token, not an identity, which is the reason the system can work without fingerprinting.

## Eligibility

| Check | Requirement |
|---|---|
| Code signature | macOS notarisation ticket, or a valid Windows Authenticode chain |
| Malware | No malicious or suspicious VirusTotal detections above threshold |
| Domain age | At least six months, verified over RDAP |
| Contact | An email address that answers a challenge |
| Binary identity | The download URL serves the bundle id you declared |

All five re-run weekly. Failures come back as machine-readable codes with eligibility dates. Full detail: [vetting and scoring](/vetting/).

## Integration by platform

### Electron

```js
import { ghan } from '@ghan/sdk'

await ghan.init({
  appId: process.env.GHAN_APP_ID,
  consent: settings.analyticsConsent,
  maxPerWeek: 1,
})

await ghan.slot('first_success')
```

Register the protocol handler in your builder config:

```json
{ "protocols": [{ "name": "GHAN", "schemes": ["ghan"] }] }
```

### Tauri

Identical SDK, identical calls. The one difference is the deep link: configure the Tauri deep-link plugin for the `ghan` scheme so the attribution token survives the click.

```json
{
  "plugins": {
    "deep-link": { "desktop": { "schemes": ["ghan"] } }
  }
}
```

```js
import { ghan } from '@ghan/sdk'

await ghan.init({ appId: import.meta.env.VITE_GHAN_APP_ID, consent: hasConsent })
await ghan.slot('first_success')
```

If the deep link is not registered, the local handoff file still carries the token and attribution still works — the rate is simply lower.

### Windows

Same SDK for Electron and Tauri builds on Windows. Register the URI scheme under `HKEY_CLASSES_ROOT\ghan` with a `URL Protocol` value; most Electron and Tauri packagers do this for you from the config above. The gate checks an Authenticode chain rather than a notarisation ticket.

### macOS

Declare the scheme in `Info.plist` via `CFBundleURLTypes` — again, usually generated by your packager. The gate checks the notarisation ticket by fetching your published DMG and validating it, so the URL you register has to be the one you actually ship.

### Node desktop apps

Supported. There is no native Swift or C# SDK yet, and the [status page](/status/) says so rather than implying otherwise.

## Cross-promotion compared to the alternatives

| | Cross-promotion (GHAN) | Paid CPI network | App store | Subscription bundle |
|---|---|---|---|---|
| Inventory | Other members' own users | Bought traffic | Store browsers | Bundle subscribers |
| Pricing | Published floor, optional bidding above it | Auction with no floor | Free listing, 15–30% of sales | Revenue share |
| Billed on | Install still in use at 48h | Usually the install event | A sale | Usage |
| Can you pay in non-cash | Yes — serve to earn credits | No | n/a | n/a |
| Who owns the customer | You | You | The store | The bundle |
| Attribution | Signed single-use token | Often probabilistic | n/a | n/a |
| Creative control | None — templated | Full | Listing copy | Listing copy |
| Suits | Apps with an existing audience | Funded acquisition | Discovery-led apps | Secondary purchases |

A longer, Mac-specific version of this decision is at [Mac app distribution platforms compared](/compare/mac-app-distribution-platforms/).

## When cross-promotion is the wrong answer

It needs you to already have users. It converts attention you have into users you do not, at a fixed exchange rate. If you launched last week with three hundred installs there is nothing to trade, and the six-month domain-age requirement in the gate would rule you out anyway.

The honest sequence is: launch, community, content, and then cross-promotion once there is an audience worth trading.

## Next

- [How it works](/how-it-works/) — the event chain and the escrow flow in full
- [SDK quickstart](/docs/sdk/) — every option the SDK takes
- [Pricing](/pricing/) — the published rate card
- [Install safety and fraud research](/research/desktop-install-network-safety-and-fraud/) — the safety standard in writing

## Questions people ask about this

### What is a desktop cross-promotion network?

A desktop cross-promotion network is a system in which independent macOS and Windows applications show each other's install recommendations to their own users and settle the exchange at an agreed price per install. Each member is both a seller of attention and a buyer of installs. GHAN is one - member apps render templated partner cards inside their own in-app lifecycle moments, attribution uses single-use signed tokens rather than fingerprinting, and money clears only after a referred install has survived 48 hours.

### Is there a cross-promotion SDK for Tauri apps?

Yes. The GHAN SDK, @ghan/sdk, supports Tauri alongside Electron and plain Node desktop applications. Integration is npm install @ghan/sdk, a ghan.init call with your app id and consent state, and a ghan.slot call at whichever lifecycle moment you choose. Tauri needs its deep-link plugin configured for the ghan:// scheme so the attribution token survives the click; everything else is identical to Electron.

### Is there a cross-promotion network for Electron apps?

Yes, and Electron is the primary target of version 1 because it is the bulk of indie desktop software. The integration is a single dependency and two calls, and the SDK renders GHAN's own templated card inside your existing UI layer rather than opening a window or injecting markup.

### What are the eligibility requirements to join?

Five automated checks. A notarised macOS build or a valid Windows Authenticode chain, a clean VirusTotal result, a domain registered at least six months ago verified over RDAP, a contact email that answers a challenge message, and a download URL that serves the bundle identifier you declared. All five are re-run weekly, so eligibility is a continuing condition rather than an entry ritual.

### What data is exchanged when an install happens?

At click, a single-use token with a nonce and a 15-minute expiry, bound to the campaign and the serving app. At install, the receiving SDK returns that token with its own ed25519 signature plus fraud signals - virtual-machine indicators, operating-system install age, a salted hardware hash, and clock skew. At clearing, coarse usage counters showing the app was still in use 48 hours later. No file contents, no personal data, no raw hardware identifiers.

### How is cross-promotion different from a paid CPI network?

A paid CPI network sells you installs from traffic sources you do not own, priced by auction, usually billed on the install event. A cross-promotion network trades installs between members, so the inventory is other products' own users, and the price can be paid in attention rather than cash. GHAN prices from a published floor that never rises, with optional second-price bidding for priority above it, and bills only on installs that survive 48 hours.

