Documentation

Users & subscriptions

SDK endpoints to identify users, register devices, and update tags.

Base path: /api/sdk. Authenticate with an SDK-type project key.

Create or identify a user

http
POST /api/sdk/users
Authorization: Bearer ek_client_...
Content-Type: application/json

{
  "external_id": "user-123",
  "tags": { "plan": "pro" },
  "identity_hash": "optional-hmac-when-verification-enabled"
}

Register a subscription

http
POST /api/sdk/users/user-123/subscriptions
Authorization: Bearer ek_client_...

{
  "type": "IOS_PUSH",
  "token": "apns-device-token",
  "device_model": "iPhone15,2",
  "device_os": "iOS 17.4",
  "app_version": "1.2.0"
}

Supported type values: IOS_PUSH, ANDROID_PUSH, EMAIL, SMS, WEB_PUSH.

Update tags

http
PUT /api/sdk/users/user-123/tags
Authorization: Bearer ek_client_...

{ "plan": "enterprise", "country": "PK" }

Track an event

http
POST /api/sdk/events
Authorization: Bearer ek_client_...

{
  "external_id": "user-123",
  "name": "purchase_completed",
  "properties": { "sku": "sku_123", "amount": 49.99 }
}

Opt out

http
POST /api/sdk/opt-out
Authorization: Bearer ek_client_...

{ "external_id": "user-123", "subscription_type": "IOS_PUSH" }

Buffering & idempotency

Identify, subscription, tag, event, and receipt calls are buffered: they return { "accepted": true } immediately and are applied by a worker, so a brief database blip never surfaces as an error. opt-out is processed synchronously so consent is confirmed.

For events, send a stable idempotency_key (e.g. a UUID per logical action). A retried request with the same key is applied exactly once; without one, a network retry would record a duplicate event.