This request adds new insider_ids to the segment of an activity previously created with /register:
Eligible devices of the added users are included in the activity segment.
These devices also receive the start push when /start is called.
The underlying merge flow is the same as /register. Eligibility filters (iOS version, push opt-in, GDPR, etc.) apply here as well.
ends_at is not part of the request. The activity TTL was fixed at /register time, and /add-users does not touch it.
This endpoint can be used only while the activity is in REGISTERED state. Once /start is called the segment is frozen and any /add-users call is rejected with 409 ALREADY_STARTED.
Endpoint and headers
POST /api/v1/live-activity/add-users
Headers
Header | Value |
|---|---|
X-Api-Key |
Body parameters
Below are the parameters for the request body.
Parameter | Description | Data Type | Required |
|---|---|---|---|
activity_id | The ID returned by /register | String | Yes |
activity_type | Must be exactly (case-sensitive) the same as the ActivityAttributes Swift class name in the iOS application. | String | Yes |
insider_ids | Target user IDs. Must contain between 1 and 10,000 elements. | String[] | Yes |
activity_type cannot be empty or whitespace-only.
activity_id cannot be empty or whitespace-only.
insider_ids must contain between 1 and 10,000 elements.
The insider_ids upper bound is config-driven (REGISTER_MAX_INSIDER_IDS, default 10,000).
Sample body
Below is a sample body for a request.
{
"activity_id": "550e8400-e29b-41d4-a716-446655440000",
"activity_type": "DeliveryActivityAttributes",
"insider_ids": [
"user-901",
"user-902",
"user-903"
]
}Below is a typical usage:
T − 1 hour: /register is called for customers with active orders (Delivery activity_type). The activity is in the REGISTERED state.
T − 30 min + 5 min: Freed stock is assigned to a new order → the partner calls POST /add-users and the new customer's insider_id is added to the segment.
T + 0: The partner calls /start → the new customer receives the "Your order is being prepared" push together with the rest.
Sample responses
Success response 200
/add-users uses the same schema as /register. The counters reflect only the insider_ids submitted in this call (not the full activity segment).
{
"status": "success",
"activity_id": "550e8400-e29b-41d4-a716-446655440000",
"matched": 3,
"added": 3,
"refreshed": 0,
"removed": 0,
"skipped": {
"push_permission_disabled": 0,
"unsupported_platform": 0,
"unsupported_os_version": 0,
"push_to_start_token_missing": 0,
"user_not_found": 0
}
}Below are the fields that return in the response.
Field | Type | Description |
|---|---|---|
status | String | Always "success" |
activity_id | String | Echo for the customer to correlate the response with the request |
matched | Int | The number of unique eligible insiders (= added + refreshed) |
added | Int | The number of newly added devices |
refreshed | Int | The number of previously registered devices whose metadata was refreshed |
removed | Int | Devices that used to be eligible but no longer are |
skipped | Object | Distribution of devices filtered out by eligibility checks, by reason |
Partial response
Like /register, /add-users can return a partial response if a portion of the profile lookup on large segments fails transiently.
{
"status": "success",
"activity_id": "uuid",
"matched": 950,
"added": 950,
"refreshed": 0,
"removed": 0,
"skipped": { ... },
"partial": true,
"unprocessed_insider_id_count": 50
}GDPR-filtered insiders may still appear in the gdpr_denied_details field.
Error responses
Refer to Error Codes for details.
Limitations
The rate limit is 1,000 requests per minute.
ends_at cannot be changed. The activity's lifetime is bound to the ends_at value set at /register time. /add-users does not extend it.
Eligibility filters apply: For newly added insider_ids, all filters (iOS version, push opt-in, GDPR, push-to-start token availability) are evaluated. Filtered devices show up in skipped and (if applicable) gdpr_denied_details.
Re-adding the same insider_id: If the device is already in the segment, it is counted as refreshed, and its metadata is updated. No error is raised.
Counters are scoped to this call: The matched, added, etc. values in the response are computed only over the insider_ids sent in this request. They are not the totals for the whole activity segment.