Overview
The Event Ingestion API accepts structured events from the AppDNA SDKs. Events are batched on the client, sent to the ingestion endpoint, and processed through the analytics pipeline into BigQuery for querying and dashboards.
Endpoints
Ingest Events
POST /api/v1/ingest/events
Authentication: SDK Key (x-api-key header)
Accepts a batch of events from the SDK. Each event follows the envelope schema defined below.
Request body:
{
"events": [
{ ... },
{ ... }
]
}
Response:
{
"accepted": 20,
"rejected": 0
}
Identify User
POST /api/v1/ingest/identify
Authentication: SDK Key (x-api-key header)
Links an anonymous device to a known user ID. Call this when the user logs in or creates an account.
Request body:
{
"anon_id": "550e8400-e29b-41d4-a716-446655440000",
"user_id": "user-12345"
}
Health Check
GET /api/v1/ingest/health
Authentication: None (public)
Returns the health status of the ingestion service.
Event Envelope Schema
Every event sent to the ingestion API must conform to the EventSchema envelope:
{
"schema_version": 1,
"event_id": "550e8400-e29b-41d4-a716-446655440000",
"event_name": "purchase_completed",
"ts_ms": 1708344000000,
"user": {
"anon_id": "660e8400-e29b-41d4-a716-446655440001",
"user_id": "user-12345"
},
"device": {
"platform": "ios",
"os": "17.0",
"app_version": "1.0.0",
"sdk_version": "1.0.0",
"bundle_version": 0,
"locale": "en_US",
"country": "US"
},
"context": {
"session_id": "770e8400-e29b-41d4-a716-446655440002"
},
"properties": {
"product_id": "premium_monthly",
"price": 9.99,
"currency": "USD"
},
"privacy": {
"consent": {
"analytics": true
}
}
}
Field Reference
| Field | Type | Required | Description |
|---|
schema_version | number | Yes | Schema version, currently 1 |
event_id | string (uuid) | Yes | Unique event identifier, generated by the SDK |
event_name | string | Yes | Name of the event |
ts_ms | number | Yes | Unix timestamp in milliseconds |
user.anon_id | string (uuid) | Yes | Anonymous device identifier |
user.user_id | string | No | Known user identifier (set after identify) |
device.platform | string | Yes | ios or android |
device.os | string | Yes | OS version |
device.app_version | string | Yes | Host app version |
device.sdk_version | string | Yes | AppDNA SDK version |
device.bundle_version | number | Yes | Config bundle version currently active |
device.locale | string | Yes | Device locale (e.g., en_US) |
device.country | string | Yes | ISO country code |
context.session_id | string (uuid) | Yes | Current session identifier |
properties | object | No | Arbitrary key-value pairs for the event |
privacy.consent.analytics | boolean | Yes | Whether the user has consented to analytics |
Events where privacy.consent.analytics is false are accepted but not processed into analytics pipelines. They are retained only for audit purposes.
Auto-Tracked Events
The AppDNA SDKs automatically track the following events without any additional code. These events are fired across all four SDKs (iOS, Android, Flutter, React Native):
Session Events
| Event Name | Trigger |
|---|
session_start | App enters foreground or new session begins |
session_end | App enters background or session times out |
app_open | App launched |
app_close | App terminated |
Push Notification Events
| Event Name | Trigger |
|---|
push_token_registered | Device push token obtained |
push_permission_granted | User grants push permission |
push_permission_denied | User denies push permission |
push_delivered | Push notification delivered to device |
push_tapped | User taps a push notification |
Purchase Events
| Event Name | Trigger |
|---|
purchase_started | User initiates a purchase flow |
purchase_completed | Purchase transaction succeeds |
purchase_failed | Purchase transaction fails |
purchase_canceled | User cancels during purchase |
purchase_pending | Purchase is pending (e.g., Ask to Buy) |
restore_started | User initiates a purchase restore |
restore_completed | Purchase restore succeeds |
Onboarding Events
| Event Name | Trigger |
|---|
onboarding_flow_started | User enters an onboarding flow |
onboarding_step_viewed | Onboarding step rendered on screen |
onboarding_step_completed | User completes an onboarding step |
onboarding_flow_completed | User finishes all onboarding steps |
onboarding_flow_dismissed | User skips or dismisses onboarding |
Paywall and Experiment Events
| Event Name | Trigger |
|---|
paywall_view | Paywall displayed to user |
paywall_close | User dismisses paywall |
experiment_exposure | User exposed to an experiment variant |
Other Events
| Event Name | Trigger |
|---|
survey_shown | Survey presented to user |
survey_completed | User submits a survey |
survey_dismissed | User dismisses a survey |
web_entitlement_activated | Web-based entitlement activated |
web_entitlement_expired | Web-based entitlement expired |
deferred_deep_link_resolved | Deferred deep link resolved on first launch |
Batching Behavior
The SDK batches events on the client to minimize network overhead:
| Setting | Default Value | Description |
|---|
| Batch size | 20 events | Events are flushed when the batch reaches this size |
| Flush interval | 30 seconds | Events are flushed on this interval regardless of batch size |
Events are also flushed immediately when the app enters the background, ensuring no data loss during session transitions.
Webhook Triggers
Certain ingestion events automatically trigger webhooks if configured on your account:
| Webhook Event | Triggered By |
|---|
onboarding.started | onboarding_flow_started event ingested |
onboarding.completed | onboarding_flow_completed event ingested |
experiment.exposure | experiment_exposure event ingested |
user.identified | /api/v1/ingest/identify called |
Webhook delivery is asynchronous and does not affect ingestion latency. See the Webhooks documentation for payload format and retry policy.