Edge API
Current SDK-facing endpoints for profiles, events, access, and purchases
The Nuxie Edge API is the transport used by the mobile SDK. Prefer the SDK for app integrations: it owns identity, event durability, signed release admission, Journey ordering, purchase evidence, retries, compression, and response coordination that a raw HTTP call does not reproduce.
Base URL
Production requests use:
https://i.nuxie.ai
The iOS SDK selects the correct endpoint from NuxieConfiguration.environment. A custom endpoint is allowed only with .custom and an explicit apiEndpoint.
Authentication and environments
POST requests include the app’s publishable key in the JSON body as apiKey. GET /status accepts it as the apiKey query parameter.
- Test keys start with
pk_test_. - Live keys start with
pk_live_.
Keys are scoped to one app and environment. Use the test key in debug builds and the live key in release builds. Retrieve both from the app’s Connect your app surface.
Publishable keys identify an app and environment; they are not workspace-administration credentials. Do not use them for dashboard mutations.
Endpoint summary
| Method | Path | Purpose |
|---|---|---|
POST |
/profile |
Fetch signed releases and the current user read model |
POST |
/event |
Commit one event |
POST |
/batch |
Deliver 1–1,000 gzip-compressed events |
POST |
/entitled |
Check Product or Feature access and optionally consume usage |
POST |
/purchase |
Process Stripe, App Store, or Google Play purchase commands |
POST |
/app-store/intro-eligibility |
Resolve App Store introductory-offer eligibility |
GET |
/status |
Verify app configuration is available at the edge |
GET |
/health |
Unauthenticated worker liveness probe |
There is no public GET /experiences/:id delivery endpoint. Experience delivery comes from the signed release control plane in /profile.
POST /profile
Fetch the runtime read model for the current app and optional identity.
{
"apiKey": "pk_test_example",
"distinct_id": "user-456",
"locale": "en-US"
}
distinct_id is optional for an app-only profile request. locale selects locale-specific content when available.
The current response shape is:
{
"schemaVersion": "nuxie.journey-plane-profile.v1",
"status": "ok",
"delivery": {
"renderBaseUrl": "https://assets.example.com/",
"assetBaseUrl": "https://assets.example.com/"
},
"features": [],
"facts": {
"properties": {},
"memberships": {},
"assignments": {
"experiment-123": {
"variantId": "treatment",
"isHoldout": false
}
}
},
"armedLegs": [
{
"reference": {
"experienceId": "experience-123",
"versionId": "version-456",
"legId": "<sha256>",
"descriptorSha256": "<sha256>"
},
"binding": { "type": "new" },
"entryCondition": { "type": "always" },
"context": { "event": {}, "responses": {} }
}
],
"releases": [
{
"locator": {
"appId": "app-123",
"environment": "test",
"experienceId": "experience-123",
"experienceVersionId": "version-456",
"versionNumber": 1,
"buildId": "build-789",
"publishedAt": "2026-08-29T12:00:00Z",
"publishedAtSeq": 1,
"legId": "<sha256>"
},
"envelope": {
"mediaType": "application/vnd.nuxie.journey+json",
"encoding": "base64",
"descriptorSha256": "<sha256>",
"descriptorSizeBytes": 1234,
"descriptorBytesBase64": "<base64>",
"signature": {
"version": 1,
"algorithm": "ed25519",
"keyId": "journey-release-2026-08",
"signatureBase64": "<base64>"
}
}
}
]
}
Every successful response uses this schema. facts contains the bounded property, segment-membership, and experiment-assignment inputs needed by the armed Journeys. Each armedLegs entry binds either a new Journey or a specific continuation generation to exactly one signed item in releases. The SDK verifies that binding and the release signature before it runs anything.
A successful profile request also records app-connection evidence used by Connect your app.
POST /event
Commit one event:
{
"apiKey": "pk_test_example",
"event": "export_limit_reached",
"distinct_id": "user-456",
"properties": {
"limit": 10,
"$set": { "plan": "free" }
},
"timestamp": "2026-08-21T12:00:00Z",
"uuid": "018f55a9-9ec4-7d7a-9b4a-1dbe8cc58410"
}
| Field | Required | Notes |
|---|---|---|
apiKey |
Yes | Publishable key for the target app and environment |
event |
Yes | Non-empty event name |
distinct_id |
Yes | Stable external or anonymous identity, up to 256 characters |
properties |
No | JSON object; may include supported user-property directives |
timestamp |
No | ISO 8601 timestamp |
uuid |
No | UUID idempotency identity; strongly recommended for direct callers |
value |
No | Numeric value associated with the event |
entityId |
No | Optional entity-scoped Feature identifier |
$anon_distinct_id |
No | Prior anonymous identity during an identify merge |
Reserved system events start with $. Applications should use SDK methods and authored actions rather than emitting Journey, Experience, purchase, or response system facts directly.
POST /batch
The batch body must be gzip-compressed and contain between 1 and 1,000 event items:
{
"apiKey": "pk_test_example",
"batch": [
{
"event": "screen_viewed",
"distinct_id": "user-456",
"properties": { "screen": "home" },
"uuid": "018f55a9-9ec4-7d7a-9b4a-1dbe8cc58410"
}
]
}
Send Content-Encoding: gzip and Content-Type: application/json. historical_migration: true is available for ordered migration traffic; ordinary apps should leave it unset.
The response reports processed, failed, and total. A partial result includes per-item errors and does not roll back successful items.
POST /entitled
Check one Feature or one Product for a user:
{
"apiKey": "pk_test_example",
"customerId": "user-456",
"featureId": "premium_export",
"requiredBalance": 1
}
Provide exactly one of featureId or productId. Optional fields include requiredQuantity, requiredBalance, entityId, sendEvent, and eventData. A request that includes sendEvent: true or eventData is a mutation and must also include a stable, caller-owned idempotencyKey (1–200 characters). Reuse that key when retrying the same logical usage request; use a new key for new usage.
The iOS hasFeature and useFeatureAndWait APIs should be preferred. They update the SDK’s local Feature view and support atomic purchase-backed usage where applicable.
POST /purchase
type selects the processor contract.
App Store transaction sync:
{
"apiKey": "pk_test_example",
"type": "appstore",
"distinct_id": "user-456",
"transaction_jwt": "eyJhbGciOi..."
}
Google Play purchase-token sync:
{
"apiKey": "pk_test_example",
"type": "playstore",
"purchase_token": "token-from-google-play",
"product_id": "premium",
"base_plan_id": "monthly",
"distinct_id": "user-456"
}
Google Play also supports package_name, product_type, and consume_purchase where the purchase contract requires them. Stripe checkout uses a separate type: "stripe" body with customerId and one or more Nuxie Product IDs.
Do not hand-build App Store requests from unverified transaction data. The iOS SDK sends the verified StoreKit 2 signed transaction and keeps finishing, retry, identity, and idempotency ownership coherent.
GET /status
Check whether the app configuration associated with a key is available:
GET https://i.nuxie.ai/status?apiKey=pk_test_example
A ready response includes the app ID, name, environment, and timestamp. The endpoint returns 503 when the edge app configuration is unavailable.
GET /health
GET https://i.nuxie.ai/health is an unauthenticated liveness probe. It does not verify one app’s configuration or Experience delivery.
Errors and retries
Error responses include a message or structured validation issues. Common status codes include:
| Status | Meaning |
|---|---|
400 |
Invalid body, identity, or command |
401 |
Missing, invalid, or revoked key |
402 |
Insufficient Feature balance |
404 |
Journey or resource not found |
409 |
Concurrent identity or Journey state conflict |
503 |
Required edge configuration or downstream authority unavailable |
Use stable UUIDs for retryable events. Purchase, Feature-use, and Journey reports have stronger domain idempotency requirements; use the SDK unless you are implementing a supported SDK transport.