POST /end

Prev Next

This request ends an activity started via /start.

  • It sends the final push message to the target devices, containing content representing the final state (e.g., "Delivered ✓", "Match ended").

  • It deletes the entire activity record on Insider's side.

  • The activity transitions to DEAD. All subsequent calls with the same activity_id return a 404 NOT_FOUND response.

/end does not physically remove the activity from the device. Insider One only delivers the final content and clears its own state. The activity on the device disappears according to Apple's stale-after/dismissal-date rules, or when the user manually swipes it away.

Endpoint and headers

POST /api/mob/v2/live-activity/end

Headers

Header

Value

Authorization

OAuth 2.0 access token

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

Same as in register; iOS ActivityAttributes class name

String

Yes

content

Live activity content

Object

Yes

title

Live activity title

String

Yes

message

Live activity body/secondary message

String

Yes

content_state

Key/value map that exactly matches the ContentState struct in the iOS application

Object

Yes

  • When target_devices is present, pushes are sent only to devices matching the (insider_id, udid) pairs in the list.

  • activity_id cannot be empty.

  • activity_type cannot be empty.

Sample body

Below is a sample request body.

{
  "activity_id": "550e8400-e29b-41d4-a716-446655440000",
  "activity_type": "OrderTrackingAttributes",
  "content": {
    "title": "Delivered ✓",
    "message": "Your order has been delivered successfully.",
    "content_state": {
      "status": "delivered",
      "deliveredAt": "2026-05-20T14:32:00Z"
    }
  }
}

Body examples

Since /end is the final push, content represents the final state; the attributes block may be resent as well.

Delivery delivered

{
  "activity_id": "<activity_id>",
  "activity_type": "DeliveryActivityAttributes",
  "content": {
    "title": "Order delivered",
    "message": "Enjoy!",
    "content_state": {
      "status": "delivered",
      "etaMinutes": 0
    },
    "attributes": {
      "courierName": "Yusuf K."
    }
  }
}

Workout finished

{
  "activity_id": "<activity_id>",
  "activity_type": "WorkoutActivityAttributes",
  "content": {
    "title": "Workout completed",
    "message": "30 min · 250 kcal",
    "content_state": {
      "phase": "finished",
      "elapsedSeconds": 1800,
      "calories": 250
    },
    "attributes": {
      "workoutType": "Running"
    }
  }
}

Match ended

{
  "activity_id": "<activity_id>",
  "activity_type": "MatchActivityAttributes",
  "content": {
    "title": "Match ended",
    "message": "Home FC 2 - 1 Away FC",
    "content_state": {
      "homeScore": 2,
      "awayScore": 1,
      "period": "full_time",
      "minute": 90
    },
    "attributes": {
      "homeTeam": "Home FC",
      "awayTeam": "Away FC"
    }
  }
}

The /end call sends the final push; the device shows this message until the stale-after period expires or the user dismisses it.

Critical rules

Irreversible: dead state

After /end is called successfully:

  • The activity record on Insider One's end is immediately deleted.

  • Every subsequent call (/start, /update, /end) with the same activity_id returns 404 NOT_FOUND.

You cannot resurrect the activity. To start fresh, create a new activity with /register.

// Response of a second /end call
{
  "error": "activity not found",
  "code": "NOT_FOUND"
}

Not physically removed from the device

The /end call only delivers the final content to the device. On the device, the live activity:

  • Is automatically dimmed when the stale-after period expires (Apple default ~4 hours).

  • Disappears from the Dynamic Island / Lock Screen when the dismissal date is reached.

  • Vanishes immediately if the user dismisses it with a manual swipe.

The content you send with /end should represent the final state ("Completed", "Finished", "Cancelled"). This is the last view the user sees until they dismiss the activity.

SDK sync gate still applies

Like /update, /end sends pushes only to synced devices:

Situation

Behavior

All target devices are synced.

Final push goes to all of them: 200 OK

Some are synced, some are not.

Pushes go to the synced ones. 200 OK + skipped_not_synced: N. The activity is still deleted.

All target devices are unsynced.

412 PUSH_TOKEN_NOT_SYNCED: No push is sent, the activity is not deleted.

If you receive 412 PUSH_TOKEN_NOT_SYNCED, the activity is still alive. Wait a short while and retry, or accept that the devices are offline and let the ends_at TTL force-close it.

Content responsibility

Like /start and /update, /end is a proxy:

  • content passes directly into the Apple push.

  • content_state enums must match the iOS values exactly.

Sample responses

Success response 200

{
  "status": "success",
  "sessions_triggered": 845,
  "skipped_not_synced": 5
}

Below are the fields that return in the response.

Field

Type

Description

status

String

Always "success"

sessions_triggered

Int

The number of final push messages delivered to Apple

skipped_not_synced

Int (omitempty)

The number of devices that did not receive the final message because their token had not synced

After the response arrives, the activity is deleted on Insider One's end. A second /end call returns 404; this is expected behavior.

Error responses

Refer to Error Codes for details.

Limitations

  • The rate limit is 100 requests per minute (burst 20), enforced per scope by the gateway.

  • Always call /end. When the activity's validity period (ends_at) expires, the record on Insider One's side is automatically deleted, but this does not send a final push to the devices. To close the user experience cleanly, always call /end explicitly.

  • Targeted end: If you send the final push to specific devices via target_devices, the activity is still fully deleted (Insider clears its state). Targeted end is not a "partial end"; it closes the activity as a whole and only sends the push to the selected devices.

  • Multiple /end calls: If the first one succeeded, the second returns 404. Treat it as an "already closed" signal, not an error.

  • The content of the /end call matters. The device shows this message until it is dismissed or stale-after expires; sending a half-baked or wrong final state is a poor user experience.

Authentication

This endpoint requires the mob-la-end scope on the access token. A token without it is rejected with 403. See OAuth 2.0 Credentials.

Sample request

curl -X POST 'https://gw.useinsider.com/api/mob/v2/live-activity/end' \
  --header 'Authorization: Bearer {access_token}' \
  --header 'Content-Type: application/json' \
  --data '{
    "activity_id": "550e8400-e29b-41d4-a716-446655440000",
    "activity_type": "OrderTrackingAttributes",
    "content": {
      "title": "Your order is on the way",
      "message": "ETA: 14:25",
      "content_state": { "status": "onTheWay" }
    }
  }'

How long the activity stays on the device

/end delivers the final content and clears Insider-side state; removal is governed by Apple.

Surface

iOS drops the activity after

Dynamic island

8 hours

Lock screen

12 hours

The app's own staleDate can dim it earlier, a dismissal date can remove it earlier, and the user can swipe it away at any time. No API call changes these, and ends_at from /register does not apply to the device.