# Building funnels with event tracking

Attribution answers “where did the user come from?”.

See [Attribution](https://docs.onside.io/sdk/attribution).

Event tracking answers “what did the user do next?”.

Use `Onside.track(_:parameters:)` to log user actions. You can then build funnels over these events.

### API

```swift
Onside.track(
    _ event: OnsideEvent,
    parameters: [OnsideEventParameter: OnsideEventParameterValue]
)
```

Pass `parameters: [:]` if you do not need any metadata.

### Events

`OnsideEvent` ships with a set of common event constants. You can also send any custom event name.

* Use `.levelAchieved`, `.purchaseCompleted`, `.registrationCompleted`, and other predefined cases when they match your action.
* Use `.custom("...")` or a string literal for everything else.

`OnsideEvent` is `ExpressibleByStringLiteral`, so this works:

```swift
Onside.track("my_custom_event", parameters: [:])
```

<details>

<summary>Full list of predefined <code>OnsideEvent</code> cases</summary>

```swift
public enum OnsideEvent: Sendable, ExpressibleByStringLiteral {
    case levelAchieved
    case purchaseCompleted
    case registrationCompleted
    case tutorialCompleted
    case subscriptionStarted
    case subscriptionRenewed
    case subscriptionCancelled
    case profileUpdated
    case contentViewed
    case contentShared
    case searchPerformed
    case addedToCart
    case checkoutStarted
    case paymentInfoEntered
    case custom(String)
}
```

</details>

### Parameters

`OnsideEventParameter` is the key type for event metadata.

It behaves like events:

* It includes a prepared set of common parameter keys.
* It does not limit your API. You can always use a custom key.
* It is `ExpressibleByStringLiteral`.

`OnsideEventParameterValue` supports:

* `String`, `Double`, `Int`, `Bool`
* arrays of these types

<details>

<summary>Full list of predefined <code>OnsideEventParameter</code> keys</summary>

```swift
public enum OnsideEventParameter: Sendable, Hashable, ExpressibleByStringLiteral {
    case achievementId
    case level
    case score
    case success
    case price
    case contentType
    case contentId
    case contentList
    case currency
    case quantity
    case registrationMethod
    case paymentInfoAvailable
    case maxRatingValue
    case ratingValue
    case searchString
    case dateA
    case dateB
    case destinationA
    case destinationB
    case description
    case `class`
    case eventStart
    case eventEnd
    case lat
    case long
    case customerUserId
    case validated
    case revenue
    case projectedRevenue
    case receiptId
    case tutorialId
    case virtualCurrencyName
    case deepLink
    case oldVersion
    case newVersion
    case reviewText
    case couponCode
    case orderId
    case param1
    case param2
    case param3
    case param4
    case param5
    case param6
    case param7
    case param8
    case param9
    case param10
    case departingDepartureDate
    case returningDepartureDate
    case destinationList
    case city
    case region
    case country
    case departingArrivalDate
    case returningArrivalDate
    case suggestedDestinations
    case travelStart
    case travelEnd
    case numAdults
    case numChildren
    case numInfants
    case suggestedHotels
    case userScore
    case hotelScore
    case purchaseCurrency
    case preferredStarRatings
    case preferredPriceRange
    case preferredNeighborhoods
    case preferredNumStops
    case custom(String)
}
```

</details>

{% hint style="warning" %}
All strings must be shorter than 100 characters.

This includes event names, parameter keys, and string values.

If a string is longer than 100 characters, the SDK truncates it to 10 characters.
{% endhint %}

### Example

```swift
import OnsideKit

// Use predefined event + predefined parameters.
Onside.track(
    .purchaseCompleted,
    parameters: [
        .price: 4.99,
        .currency: "EUR",
        .quantity: 1,
        .validated: true
    ]
)

// Use predefined event + custom parameter key (string literal).
Onside.track(
    .contentViewed,
    parameters: [
        .contentId: "post_123",
        "screen": "home"
    ]
)

// Fully custom event + custom parameters.
Onside.track(
    "my_custom_event",
    parameters: [
        "ab_test_variant": "B",
        "scores": [10, 20, 30]
    ]
)
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.onside.io/sdk/attribution/building-funnels-with-event-tracking.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
