REST API
Edge API endpoints for events, profiles, entitlements, and purchases
The Nuxie edge API handles all SDK communication. These endpoints process events, deliver profiles, check entitlements, and sync purchases.
Base URL
All endpoints are served from your Nuxie ingest URL:
https://i.nuxie.ai
Authentication
Every request must include your API key. For POST endpoints, include the key in the request body. For GET endpoints, include it as a query parameter.
{
"apiKey": "nux_live_abc123..."
}
API keys are scoped to a single app and environment (test or live). Generate keys in the dashboard under Settings > API Keys.
Warning: Never expose live API keys in client-side code that is not compiled into a native app. The iOS SDK handles key management automatically.
POST /event
Submit a single event.
Request body
{
"apiKey": "nux_live_abc123",
"event": "signup_completed",
"distinct_id": "user-456",
"properties": {
"plan": "premium",
"$set": {
"email": "user@example.com"
}
},
"timestamp": "2026-01-15T10:30:00Z",
"value": 9.99,
"entityId": "org-789"
}
| Field | Type | Required | Description |
|---|---|---|---|
apiKey |
string | Yes | Your API key |
event |
string | Yes | Event name |
distinct_id |
string | Yes | User identifier |
properties |
object | No | Event properties and directives ($set, $set_once, $unset, $increment) |
timestamp |
string | No | ISO 8601 timestamp (defaults to server time) |
uuid |
string | No | Idempotency key (auto-generated if omitted) |
value |
number | No | Numeric value associated with the event |
entityId |
string | No | Entity identifier for multi-entity features |
$anon_distinct_id |
string | No | Anonymous ID for identity merge on $identify events |
Response
{
"status": "ok",
"eventId": "evt_abc123",
"customerId": "cust_789",
"payload": { ... }
}
The response may include additional fields depending on the event type:
customer– Returned for identity eventsjourney– Returned for journey lifecycle eventsusage– Returned for$feature_usedevents with remaining balancefeaturesMatched– Count of matched features for custom eventsdeduped–trueif the event UUID was already processed
POST /batch
Submit multiple events in a single request. The request body must be gzip-compressed.
Request headers
Content-Encoding: gzip
Content-Type: application/json
Request body (before compression)
{
"apiKey": "nux_live_abc123",
"batch": [
{
"event": "page_viewed",
"distinct_id": "user-456",
"properties": { "page": "pricing" },
"timestamp": "2026-01-15T10:30:00Z"
},
{
"event": "button_clicked",
"distinct_id": "user-456",
"properties": { "button": "subscribe" },
"timestamp": "2026-01-15T10:30:05Z"
}
]
}
| Field | Type | Required | Description |
|---|---|---|---|
apiKey |
string | Yes | Your API key |
batch |
array | Yes | Array of event objects (1–1,000 events) |
historical_migration |
boolean | No | Set to true to process events in chronological order |
Each event in the batch uses the same fields as POST /event (minus apiKey).
Response
{
"status": "success",
"processed": 2,
"failed": 0,
"total": 2
}
If some events fail, the response status is "partial" and includes an errors array with the index and error message for each failure. Individual failures do not abort the batch.
POST /profile
Fetch the runtime profile for a user. The profile contains campaigns, segments, flows, features, experiment assignments, and active journeys.
Request body
{
"apiKey": "nux_live_abc123",
"distinct_id": "user-456",
"locale": "en-US"
}
| Field | Type | Required | Description |
|---|---|---|---|
apiKey |
string | Yes | Your API key |
distinct_id |
string | No | User identifier (omit for app-only config) |
locale |
string | No | User locale for localized content |
Response
{
"status": "ok",
"campaigns": [ ... ],
"segments": [ ... ],
"flows": [ ... ],
"customer": {
"id": "cust_789",
"properties": { ... },
"entitlements": { ... },
"segments": { ... }
},
"experiments": {
"pricing_test": {
"experimentKey": "pricing_test",
"variantKey": "variant_b",
"status": "running",
"isHoldout": false
}
},
"features": [ ... ],
"journeys": [ ... ]
}
If distinct_id is omitted, the response includes only app-level configuration (campaigns, segments, flows) without customer-specific data.
POST /entitled
Check whether a user has access to a feature or product.
Request body
{
"apiKey": "nux_live_abc123",
"customerId": "user-456",
"featureId": "premium_export"
}
| Field | Type | Required | Description |
|---|---|---|---|
apiKey |
string | Yes | Your API key |
customerId |
string | Yes | User identifier (distinct ID) |
featureId |
string | One of | Feature external ID to check |
productId |
string | One of | Product ID to check (alternative to featureId) |
requiredQuantity |
number | No | Minimum quantity required for metered features |
requiredBalance |
number | No | Minimum balance required |
entityId |
string | No | Entity ID for per-entity balance checks |
sendEvent |
boolean | No | Emit an analytics event on success |
eventData |
object | No | Additional properties for the analytics event |
Response (feature check)
{
"status": "ok",
"entitled": true,
"feature": {
"id": "premium_export",
"type": "boolean"
}
}
For metered features, the response includes balance information.
POST /purchase
Sync a purchase transaction from a payment provider.
Request body (App Store)
{
"apiKey": "nux_live_abc123",
"type": "appstore",
"distinct_id": "user-456",
"transaction_jwt": "eyJhbGciOi..."
}
| Field | Type | Required | Description |
|---|---|---|---|
apiKey |
string | Yes | Your API key |
type |
string | Yes | "appstore" |
distinct_id |
string | Yes | User identifier |
transaction_jwt |
string | Yes | Signed transaction JWT from StoreKit 2 |
Additional fields depend on the purchase type. The SDK handles constructing the correct payload.
Request body (Google Play)
{
"apiKey": "nux_live_abc123",
"type": "playstore",
"purchase_token": "google-play-purchase-token",
"product_id": "premium",
"base_plan_id": "monthly"
}
| Field | Type | Required | Description |
|---|---|---|---|
apiKey |
string | Yes | Your API key |
type |
string | Yes | "playstore" |
distinct_id |
string | No | User identifier. When omitted, Nuxie uses Google Play external/obfuscated account identifiers when present, then a stable purchase-token fallback. |
purchase_token |
string | Yes | Google Play purchase token |
package_name |
string | No | Android package name. When provided, it must match the Play Store app configured in Nuxie. |
product_id |
string | No | Google Play product ID. Recommended when known; omit for token-only multi-product one-time purchases and set product_type to "one_time". |
base_plan_id |
string | No | Google Play subscription base plan ID |
product_type |
string | No | "subscription" or "one_time" when you want to skip API-type inference. Use "one_time" when omitting product_id for a multi-product purchase token. |
consume_purchase |
boolean | No | Consume a completed one-time product purchase after validation |
GET /flows/
Fetch a single flow payload by ID.
GET /flows/ver_abc123?apiKey=nux_live_abc123
Returns the raw published flow definition for rendering in the SDK.
Note: The
:idis a published version ID (ver_...) from the profile payloadflowsarray.
GET /status
Check whether app configuration is available.
GET /status?apiKey=nux_live_abc123
Response
{
"status": "ok",
"app": {
"id": "app_123",
"name": "My App",
"environment": "live"
},
"timestamp": "2026-01-15T10:30:00Z"
}
Returns 503 if app configuration has not been synced to the edge yet.
GET /health
Unauthenticated liveness probe.
{
"status": "ok",
"timestamp": "2026-01-15T10:30:00Z"
}
Error handling
All errors follow a consistent format:
{
"status": "error",
"message": "Description of the error"
}
| HTTP Status | Meaning |
|---|---|
400 |
Invalid request body or parameters |
401 |
Missing or invalid API key |
402 |
Insufficient balance (metered feature usage) |
404 |
Resource not found |
503 |
Edge configuration not available |
Best practices
- Use the SDK instead of calling the API directly. The SDK handles batching, compression, retries, and identity management.
- Always include a
uuidfield for event idempotency if you are calling the API directly. - Use
POST /batchfor high-volume event ingestion. Compress the payload with gzip. - Check
POST /statusafter initial setup to verify your app configuration has propagated to the edge.
Next steps
- System Events – Reference for
$-prefixed system events - Webhooks – Configure App Store webhooks
- iOS SDK Installation – Get started with the SDK