# Quickstart

Integrate the ActivationPal SDK into an iOS app and see events on the dashboard.

Other guides: [events.md](events.md) · [revenuecat.md](revenuecat.md) · [agent-api.md](agent-api.md) · [apps.md](apps.md) · [apple-ads.md](apple-ads.md)

## 1. Get the app slug and API key

Create the app at `https://activationpal.com/dashboard/apps/new` (or dashboard → gear → **All apps** → add apps). It returns:

- **slug** — the app's id, e.g. `myapp`; the `app` value in `configure` and the agent API.
- **API key** — `ap_pk_...`, shown once (only a hash is stored). Missing? Ask your user, or rotate it ([apps.md](apps.md)).

## 2. Add the SDK

One Swift file, no dependencies, iOS 15+. Add it to the app target in Xcode:

```bash
curl -fsSL https://activationpal.com/sdk/ActivationPal.swift -o MyApp/Services/ActivationPal.swift
```

## 3. Configure at launch

```swift
@main
struct MyApp: App {
    init() {
        ActivationPal.configure(app: "myapp", key: "ap_pk_YOUR_KEY")
    }
}
```

With RevenueCat: configure it first and pass its user id — this joins revenue events to client events ([revenuecat.md](revenuecat.md)):

```swift
Purchases.configure(withAPIKey: "appl_YOUR_RC_KEY")
ActivationPal.configure(app: "myapp", key: "ap_pk_YOUR_KEY", userId: Purchases.shared.appUserID)
```

`configure` is thread-safe, never blocks, and no-ops if configuration failed; events buffer in memory and on disk. User id known later: `ActivationPal.setUserId(_:)`.

Configuring sends `first_open` (once per install), `app_open` (each session), and the Apple Search Ads attribution token automatically.

## 4. Instrument the fixed events

Names are fixed — the dashboard's funnel and paywall cards match on them. Full vocabulary: [events.md](events.md).

```swift
// Onboarding: one call per screen, in order, index from 0.
// `answer` records the user's choice on question screens.
ActivationPal.onboardingStep(0, id: "goal", answer: "lose_weight")
ActivationPal.onboardingStep(1, id: "notifications")
ActivationPal.onboardingCompleted()

// Paywall: `placement` is where it appeared (e.g. "onboarding", "settings").
ActivationPal.paywallShown("onboarding")
ActivationPal.paywallPlanSelected("yearly")
ActivationPal.paywallPurchased("yearly")
ActivationPal.paywallDismissed()

// Custom events: any snake_case name, props of String/Bool/Int/Double.
ActivationPal.track("workout_logged", ["type": "run", "duration_min": 42])
```

## 5. Verify

- Run the app. Flush: every ~10 s, immediately at 20 buffered events and on background. Events hit the dashboard live feed seconds later.
- DEBUG builds print `[ActivationPal] flushed N event(s)` in the Xcode console.
- `env`: `debug` (DEBUG build), `testflight`, `release` (App Store) — filterable in the feed and in [`get_events`](agent-api.md).
- `first_open` fires once per install; delete and reinstall to fire it again.
