Signpost events
Send low-volume funnel milestones such as paywall views and onboarding steps to RevenueHog, including the reserved onboarding_step event that powers the funnel.
Signpost events are low-volume milestones around revenue, such as a paywall view or an onboarding step. They are not a general analytics pipeline: each app gets at most 32 distinct event names. No SDK method wraps this endpoint yet, so send it with a plain HTTP request.
Send events
POST /api/sdk/v1/events
Authorization: Bearer dt_… (omit when unattested)
Content-Type: application/json
{
"bundleId": "com.example.app",
"events": [
{
"name": "paywall_viewed",
"appUserId": "user_42",
"at": 1755798000000,
"properties": { "placement": "onboarding" }
},
{
"name": "onboarding_step",
"appUserId": "user_42",
"at": 1755798001000,
"properties": { "step": "choose_plan", "index": 3, "value": "annual" }
}
]
}bundleId can sit on the envelope or on the first event; one batch is always one app. Use the same appUserId you send to identify (the $anon_ ID before login).
Rules
| Rule | Limit | What happens otherwise |
|---|---|---|
| Events per batch | 1 to 50 | 400 with missing events or too many events (max 50) |
| Event name | snake_case, starts with a letter, [a-z0-9_], at most 48 characters, no rh_ prefix | Event dropped, reported as invalid_name |
appUserId | Required per event, trimmed to 191 characters | Event dropped, reported as missing_app_user_id |
| Distinct names per app | 32, admitted first come | Event dropped, name listed in rejectedNames |
properties | Flat JSON object, at most 2,048 characters serialized | Properties stripped; the event still counts |
at | Epoch milliseconds or ISO 8601, clamped to the last 7 days and at most 5 minutes ahead | Unparseable values become the server time |
Per-event problems never fail the batch.
Response
{ "ok": true, "stored": 1, "dropped": [{ "reason": "invalid_name", "name": "Bad Name" }], "rejectedNames": ["over_budget_name"] }dropped and rejectedNames appear only when non-empty. An unresolvable bundle ID returns { "ok": true } and stores nothing.
The onboarding funnel
The reserved name onboarding_step powers the onboarding stage of the Funnel:
- Fire one event when a step is shown, with
step(a snake_case name) andindex(an integer 0 to 99, the display order, stable across builds). - When the step captures a choice, add
valuewith the answer ("annual","fitness"). Strings, numbers and booleans are accepted and stored as a string of up to 48 characters. Never send PII or free text. Re-send with the final value if the user changes their pick.
Steps appear in index order. A step first seen without an index sorts last (index 99); if a lower index arrives later, it wins. A step whose step property is not a valid name is stored as a plain event and never reaches the funnel. For users you also identify and attribute, conversion is segmented by each step's value.
Suggested names beyond onboarding: onboarding_started, onboarding_completed, paywall_viewed, paywall_dismissed, purchase_initiated, feature_used (with a feature property).
Client guidance
Batch client-side: flush at about 10 queued events, when the app goes to the background, and on next launch. Retry 429 and 5xx with backoff; do not retry other 4xx responses.
Related
Last updated on
Attribution
How RevenueHog links store purchases to your own user IDs with identify and attribute, how anonymous IDs re-point after login, and the Apple Ads token.
Server-driven paywall
Let the RevenueHog dashboard decide which products your paywall offers and in what order, with a compiled-in fallback, a TTL cache and the impression beacon.