InAppEventType: the in-app event enum and the aliasing rejections
The mobile SDKs report in-app engagement (impression / click / dismiss) with one typed enum. This page is the contract for that enum: what the server accepts, what it rejects with a 422, and the exact fix per language.1. Why mobile does not speak raw strings
Every engagement event lands on one endpoint:POST /sdk/in-app/events. The server validates type against a fixed set — impression, click, dismiss — before it writes the event into your analytics, so the same visitor’s journey reads as one event family on the contact timeline.
The SDKs expose that set as a typed enum rather than an open string, so a mistyped value fails at compile time in your IDE instead of at runtime against the API. In TypeScript/React Native the enum is a string-literal union, so the compiler rejects anything outside the three literals before the event ever leaves the device.
When an invalid value does reach the server — a hand-rolled HTTP call, or a value an older SDK passed through unchecked — the response is a 422 validation error and the event is dropped. Nothing is written, and no retry will change the outcome until the value is corrected.
2. The three allowed values
Exactly three event types are accepted, with one meaning each:
These are the only bases the server order-reads. Any other string is rejected.
3. Forbidden shapes — each rejected with a 422
All three of these compile in at least one language and then fail at the API: Raw string literals where the language offers a real enum. On Android the Kotlin enum exists, so a literal gets past no compiler check you couldn’t have caught:OrbitAnalytics.IMPRESSION or "InAppEventType.CLICK" read as plausible references but carry a value the server has never heard of:
4. The fix, per language
Swift (iOS) —InAppEventType is a String-backed enum; use member shorthand:
InAppEventType carries its wire value; import the enum and reference the case:
InAppEventType is the string-literal union "impression" | "click" | "dismiss", so the literal is the enum and the compiler enforces it:
5. The same event in all three languages
Reporting one impression for the first card in the feed:{ "type": "impression", "surface_id": "…", "anonymous_id": "…" } — so a visitor who moves between your iOS, Android, and React Native apps lands one consistent engagement history.
6. Debugging the 422 payload
A rejected event comes back as the standard Orbit error envelope.type failures surface as a VALIDATION_ERROR whose details.issues pin the offending field:
details.issues[0].path — when it points at type, compare the rejected value against the table in section 2 and switch to the enum form from section 4. Because reportEvent is fire-and-forget in every SDK, a rejection never throws into your UI; if you need to see it, enable the client’s debug flag and the rejection is logged with the value that failed. Correct the value and re-send — the event idempotency contract dedupes a corrected re-send of the same event.
Where to go next
- Swift SDK — full iOS quickstart.
- Android SDK — full Kotlin quickstart.
- React Native SDK — full RN quickstart.
- Build the in-app engagement channel — authoring and targeting the surfaces these events measure.