Skip to main content
The Apsio SDKs write every signal they record to a store on the device, already masked: text a mask hides never reaches the disk. Your app’s remote configuration then decides, for each kind of data, what is sent, when, and how long the rest stays on the device before it is deleted. A session left out of the sample can still send the minutes before a crash. Nothing is written while consent is withdrawn or the user has opted out; an app that needs consent first withdraws it right after start, until the user agrees (privacy). The app’s start options and the policy’s capture settings still decide what is recorded at all: replay, for example, is recorded only if the app turns it on. The store only decides what leaves the device.

The families

The store holds seven families of data, and each has its own mode:

What leaves the device

Each family is in one mode:
  • Always: sent as it is recorded. A family you have not set is in this mode, and the session summary stays in it, so crash-free rates and session counts are exact (within your plan’s fair use).
  • Sampled: sent from a share of sessions, decided once per session by a hash of its id, as sampling describes. This is the session sampling rate, now set per family.
  • On a trigger: kept on the device and sent only when a trigger fires in the session, or on a remote send request.
  • Never: kept on the device until it expires, and sent only on a remote request.
In a sampled errors family, the first error of each issue in a calendar month always passes: the device keeps a set of one-way fingerprints of the errors it sent this month.

Triggers

A trigger is a crash or a termination without a crash report, an error (any record at Error severity or above, handled errors included), an ANR or hang, or a named event your app reports with Apsio.trigger(name). When one fires, the families whose policy lists it send what the device holds from the minutes before it: the window, 5 minutes by default and up to 60.
  • Which families. Families in on-a-trigger mode, and sampled families in a session outside the sample, when they list that trigger. An always family is already sent; a never family ignores triggers.
  • When. An error, an ANR or hang, or a named event releases its window at once, and it goes with the next upload. A crash is found at the next launch, since the app was not running, and the window from the session that crashed is sent then. Records reach the device’s disk within moments of being written, so a crash loses at most the last moments before it.
  • For the rest of the session. After a trigger in the running app, the triggered families stay released until the session ends.
  • Window edges. Records are stored in batches of about 10 seconds, so up to about 10 seconds before the window may be sent too.
  • Replay. A trigger sends at most the session’s replay limit: the last minutes of the window.
React Native behaves as the native SDK under it: a fatal JavaScript error is written at once and handled like a crash at the next launch, and Apsio.trigger exists in JavaScript too.

How long data stays on the device

  • Retention: 24 hours by default, set from 1 hour to 7 days. It counts from each record’s own time, and applies to records already released but not yet sent (on a device that is offline, for example).
  • Cap: 20 MiB per app on each device, of which at most 10 MiB is replay. Your policy can lower both.
  • When the store is full, the oldest records go first: replay over its own share first, then the other families, with session summaries and errors last.
Apsio accepts records up to 7 days old, so a late upload is stored, and its retention in Apsio counts from when Apsio received it.

When data is deleted from the device

  • After it is sent: once Apsio confirms the upload. A record Apsio rejects as invalid is discarded too.
  • When its retention ends, sent or not.
  • When the store reaches its cap, oldest first, as above.
  • At once, when the user opts out or withdraws consent, or the kill switch is on: the whole store, including replay held on the device and records not yet sealed into a batch for upload.
  • On a remote delete (below), at the device’s next policy fetch.
Besides the records, the device keeps three small things: the app user’s hash (the value your app passes to setUser, never a raw id) for 7 days after it was last set, so a remote request for that user can still find the device; this month’s error fingerprints; and the ids of remote requests it already served. An opt-out or withdrawn consent deletes the first two as well; the served request ids hold no personal data.

Remote requests

An owner or admin can ask one install, or every install of one app user, to act on what it holds:
  • Send uploads what the device holds.
  • Delete deletes what the device holds and what it has queued unsent.
Both cover only the families the request names, or every family when it names none, including those set to never and the session summaries. A device checks for requests each time it fetches the policy, at launch and at the policy’s fetch interval (15 minutes by default) while the app runs, and serves a request once. A request for an app user reaches only that user’s records, and only on a device where the app set that user’s hash in the last 7 days. A request lasts up to 7 days, and a project has at most 100 open at a time. A request never overrides consent, an opt-out or the kill switch, and never brings back what they deleted. Requests travel inside the app’s policy as a one-way hash, never as the install or user id, and Apsio stores only that hash and the id’s last 4 characters. The device answers with an apsio.remote_request record that says whether it sent, deleted or had nothing, and how many records. Every request, and its cancellation, is in the organization’s audit log, without the id it targets.

Setting it

In the console, SDK › Signals sets, for each app, each family’s mode, rate, triggers and window, and the retention and cap on the device, and lists the device requests and their state (open, delivered, expired or canceled). On a user’s or a session’s page, Device data opens a request: Send to Apsio or Delete on the device, for every family or the ones you pick, lasting 1, 3 or 7 days. Members can see these settings; owners and admins change them, and every change is in the audit log. A change is published to the app’s policy at once and reaches each device at its next fetch. For scripts, the same settings are in the console API: GET and PUT /v1/orgs/{orgId}/projects/{projectId}/apps/{appId}/instrumentation, and /v1/orgs/{orgId}/projects/{projectId}/device-requests to list, open and cancel requests; the API reference lists their fields. How devices read the policy is in the specification: the policy’s fields and instrumentation.