Authentication
Send Authorization: Bearer YOUR_APP_SDK_KEY on every SDK request. The key determines the organization and application. Do not send a client-controlled organization ID or use an Apple private key. These endpoints are for native clients; account/dashboard administration uses a different authenticated boundary.
Authorization: Bearer YOUR_APP_SDK_KEY
Content-Type: application/jsonPOST /api/v1/events
Consent must be true. Send 1–100 events with stable IDs and timestamps. The example is an onboarding event, not a payment.
curl --fail-with-body https://aplyna.com/api/v1/events \
-H "Authorization: Bearer YOUR_APP_SDK_KEY" \
-H "Content-Type: application/json" \
--data '{"consent":true,"events":[{
"event_id":"evt_REPLACE_WITH_UNIQUE_ID",
"installation_id":"YOUR_PERSISTED_INSTALLATION_ID",
"name":"onboarding_step_viewed",
"flow_id":"YOUR_FLOW_ID",
"step_id":"welcome",
"occurred_at":"REPLACE_WITH_CURRENT_ISO8601_TIMESTAMP",
"properties":{"app_version":"1.0.0"}
}]}'| Response | Meaning |
|---|---|
| 202 Accepted | Validated ingestion response with accepted, duplicates, received_at and cloud delivery status. SDK receipt is not verified payment confirmation. |
| accepted | Number of newly accepted events. |
| duplicates | Events already stored under the same app and event ID. |
| received_at | Server receipt timestamp; separate from client occurred_at. |
| cloud | Event-forwarding status. App processing configuration may differ; this does not mean a store is connected. |
A curl timestamp placeholder must be replaced with a current ISO timestamp before running. Reuse the event ID when retrying that same event. The app-level ingestion rate limit is 600 requests per minute; handle 429 responses with bounded backoff.
GET /api/v1/config
| Query | Value |
|---|---|
| flow_id | Required published flow belonging to the SDK key's app. |
| schema_version | 1 or 2, representing the maximum schema the client understands. Defaults to 1. |
curl --fail-with-body --get https://aplyna.com/api/v1/config \
-H "Authorization: Bearer YOUR_APP_SDK_KEY" \
--data-urlencode "flow_id=YOUR_FLOW_ID" \
--data-urlencode "schema_version=2"Returns 200 and the published configuration, including schema_version and steps. ETag identifies the immutable release; Cache-Control is private, max-age=30. Send If-None-Match with the returned ETag to receive 304 if unchanged. A 304 has no JSON body. A newer layout than the declared schema returns 422; an unpublished or unavailable flow returns 404.
GET /api/v1/assignment
| Query | Value |
|---|---|
| flow_id | Required published app-scoped flow. |
| installation_id | Required persisted pseudonymous installation identity. |
curl --fail-with-body --get https://aplyna.com/api/v1/assignment \
-H "Authorization: Bearer YOUR_APP_SDK_KEY" \
--data-urlencode "flow_id=YOUR_FLOW_ID" \
--data-urlencode "installation_id=YOUR_PERSISTED_INSTALLATION_ID"{
"variant": "A",
"experiment_id": null,
"flow_id": "YOUR_FLOW_ID"
}The response uses Cache-Control: no-store. An active experiment can return its ID and A/B variant. This request does not record an exposure. Attach the returned assignment to exposure and conversion events.
Errors and retries
{"error":"Readable error message"}| Status | Action |
|---|---|
| 400 | Fix malformed JSON or schema validation failures; inspect the error field. |
| 401 / 403 | Check the app SDK key and authorization. Do not retry indefinitely. |
| 404 | Check the flow ID, publication and application scope. |
| 413 | Reduce request size below the body limit. |
| 422 | Check timestamps, semantic validation or requested configuration schema. |
| 429 | Rate limit reached; wait and use bounded retry/backoff. |
| 5xx / network failure | Retain queued IDs and retry later, with a native fallback for configuration. |