Client SDKs
The Arsel client SDKs run inside your own app — a website, an Android app, or an iOS app — and do two things:
- Events and identity. Record what a person does (
product.viewed,cart.updated) and who they are, without you writing queueing, retry, or session logic. - Push notifications. Register the device so Arsel can deliver notifications to it, and report back what happened to each one.
These are two independent subsystems. Events and identity work on a device that has never granted notification permission and has no push token at all — a visitor who declines notifications still has a contact and a behavioural history. Only delivery needs push.
Available SDKs
| Platform | Package | Requirements |
|---|---|---|
| Web | @arsel.sa/web-sdk — ESM + UMD, no dependencies | Chrome/Edge 79+, Firefox 72+, Safari 16.4+ |
| Android | sa.arsel:core + sa.arsel:push-fcm | minSdk 23, Firebase Messaging (push only) |
| iOS | Swift Package, zero dependencies | iOS 15+, Swift 5.10 |
All three SDKs follow Semantic Versioning. The public API and the wire contract are frozen within a major version — additive changes ship as minor releases, and anything breaking waits for the next major. A breaking change costs every integrator an app-store release, so they are rare by design.
Events the SDKs record for you
Beyond the events you send with track(), every SDK records a small set of its own. They are namespaced arsel. — a prefix track() refuses, so one of your own event names can never collide with one of these — and they arrive as ordinary events: segmentable, and usable as automation triggers.
| Event | When | Properties |
|---|---|---|
arsel.app_installed | the first time the SDK ever runs — after an app install, or on a browser's first visit | app_version (mobile), sdk_version, platform |
arsel.session_start | the app is opened or the page becomes visible, when the last session is more than 30 minutes old | — |
arsel.session_end | the session that just closed, backdated to when the app or tab actually went away | duration_seconds |
arsel.identify | you called identify() with at least one identifier | — |
arsel.screen_view | you called screen() | screen_name, plus anything you passed |
You do not define these — they appear in your event list on their own, the first time a device sends one.
A session ends after 30 minutes away, but nothing on the device wakes up to notice: arsel.session_end is emitted on the next open, backdated to when the app or tab actually left. Someone who never comes back produces a session that stays open and no end event — an unclosed session is better than a fabricated end time. Build reporting on session_start, and treat session_end as a best-effort duration.
On mobile, arsel.app_installed means a real app install, and it fires again after an uninstall and reinstall. On the web there is no install to observe, so it means "the first time we saw this browser" — clearing site data or opening a private window produces another one. Web install counts run high, and no in-page SDK can do better.
Devices and browsers that were already running an older SDK do not produce an install event when they update. They are recognised and skipped, so upgrading an SDK does not report your existing audience as a wave of new installs — which also means install-based segments start empty and fill from the upgrade forward.
Source code
Every SDK is open source under the MIT licence, and each repository is the reference for its own platform — versioned with the code you install, so it never describes a release you are not on. The platform pages above link straight into it.
| Platform | Repository |
|---|---|
| Web | Arsel-SA/arsel-web-sdk |
| Android | Arsel-SA/arsel-android-sdk |
| iOS | Arsel-SA/arsel-ios-sdk |
Issues and questions about an SDK are best raised on its own repository, where they sit next to the code.
Authenticating an SDK
Client SDKs authenticate with a client key, not an API key:
pub_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
A client key is publishable — it is designed to be compiled into your app bundle or served in your page's JavaScript, exactly like a Google Maps or Stripe publishable key. It is not a secret, and it grants far less than a be_ API key: it can record events and register devices for your organization, and nothing else. It cannot read contacts, send campaigns, or manage your account.
Your be_ API key must never ship in client code. See Authentication for the full comparison.
For web, a client key is additionally constrained by an origin allowlist — you register the domains allowed to use it, and requests from anywhere else are rejected. Native apps send no Origin header and are not subject to it.
Find your client key in the Arsel Dashboard under Integration > Push, and see Setting Up Push for the rest of the configuration.
Binding a device to a known contact
Registering a device tells Arsel the device exists. Binding it to a contact tells Arsel whose device it is — which is what makes targeted campaigns possible.
The SDKs handle this themselves. Every registration carries the SDK's anonymous ID, so a device that registers before anyone signs in still resolves to the same contact its events are building — and when your app calls identify(), that contact merges forward.
If your backend already knows who is signed in and you would rather assert the binding from your server, read the installation ID from the SDK and call Register Device with your be_ API key. A server-asserted binding overrides the anonymous one.
Server-side alternatives
Everything the SDKs do has a server-side equivalent, which is the right choice when you are migrating existing device tokens or your app cannot embed an SDK:
| Task | Server endpoint |
|---|---|
| Record an event | Send Event |
| Register a device | Register Device |
| Revoke a device | Unregister Device |
| Inspect a contact's devices | List Contact Devices |
| Send to one contact | Send Push |
Delivered, opened, and clicked counts are reported by the SDK on the device. A device registered server-side without an embedded SDK still receives notifications, but contributes no delivery or engagement data — those metrics read zero for it. Register devices server-side for migration; embed the SDK for measurement.