# The five GHAN lifecycle slots

> GHAN has exactly five placement slots, all of them inside the running application and none of them inside an installer. The host app calls a slot when it decides a moment has arrived; the SDK renders a templated card with a partner icon, a name and one line, and nothing else is possible.

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

---

## The five slots

### `install_complete`

Fires on the first launch after installation. The person is demonstrably in install mode — they have just completed one installation voluntarily and the friction of a second one is at its lowest point it will ever be.

Renders a single card below the app's own first-run content. Never a modal, never before the host app's own onboarding.

### `first_success`

Fires the first time the application does the thing it exists to do — the screenshot is captured, the file is converted, the database connects, the recording is saved. The host app defines what success means, because only the host app knows.

This is the highest-trust moment in a desktop application's entire lifecycle and it is the slot most members enable first.

### `update`

Fires after an update lands. You have already earned a moment of the person's attention to tell them what changed; a single card beside the release notes costs nothing extra in interruption.

### `idle`

Fires at a deliberate pause the host app chooses — a long export, an empty state, a settings screen. The cheapest inventory in the network in interruption terms, and correspondingly the lowest-converting.

### `uninstall_intent`

Fires when the person is leaving. The only moment in the list where showing a competing product is unambiguously good for the person rather than merely acceptable, and the one slot where GHAN allows same-category placements by default.

## What a slot renders

Always the same shape, always rendered by the SDK inside the host application's own UI layer:

- The partner's icon, fetched from a URL on GHAN's CDN
- The partner's name
- One generated line of copy
- An Install button
- A dismiss affordance

That is the complete list. There is no code path in the SDK that renders remote HTML, remote JavaScript, a video, an animation, or a partner-supplied image outside the icon. This is a property of the implementation rather than a term in an agreement, which matters because agreements are not checkable by a reviewer and code is.

## Calling a slot

```js
// Returns immediately and resolves to a result you can ignore.
const result = await ghan.slot('first_success')

// result.rendered  -> boolean, false if capped, excluded or nothing matched
// result.chainId   -> the event chain, if one was created
```

If GHAN has nothing relevant, if your frequency cap is reached, if the person has dismissed too many cards, or if your kill switch is on, `rendered` is `false` and nothing appears. The host application never has to handle an error to stay safe.

## Slot hygiene the SDK enforces

1. Never two cards in one session.
2. Never a card during the host app's own first-run flow unless `install_complete` was explicitly called there.
3. Never the same partner twice within 30 days to the same install.
4. Never a card to an install that has dismissed three in a row.
5. Never anything while the host app reports consent as false.

These are defaults in the SDK, not server policy, which means a partner cannot ask GHAN to relax them for their campaign.

## The canary

The server periodically sends a signed liveness probe that the SDK answers with its own signature. That is how GHAN can prove a slot is genuinely live in a shipped build rather than merely declared in a dashboard — and it is how an app claiming inventory it does not have gets suspended. See [fraud prevention](/fraud-prevention/).

## Questions people ask about this

### Why are there no installer-time placements?

Because installer-time placements are what killed the previous generation of desktop cross-promotion networks. An offer inside an installer competes for the same click as the Next button, which makes accidental acceptance the most profitable outcome for everyone except the person installing. Antivirus vendors correctly treat that pattern as a malware signature. GHAN has no installer-time slot and will not add one.

### Which slot performs best?

first_success, by a distance, because it is the only moment where the person has just had a good experience with software and is briefly receptive to more of it. uninstall_intent converts well too, for the opposite reason - a person leaving genuinely wants an alternative, and it is the one moment where showing a competitor is a service rather than a leak.

### Can I add my own slot?

Not in version 1. The five slots are fixed because a custom slot is an unbounded surface, and an unbounded surface is how a templated network becomes an ad network. If a sixth moment turns out to be genuinely distinct and genuinely respectful, it becomes a slot for everyone rather than a private extension.

### How often will a card appear?

Whatever cap you set. The SDK enforces a host-supplied frequency cap and defaults to conservative. Most members run one card per week or fewer, and the 48-hour clearing rule means an irrelevant card shown often earns less than a relevant card shown rarely.

