Live Activity Stream

Start, update, and dismiss Live Activities with a stable stream key.

Live Activity streams use a stable stream_key for the thing you want to keep visible. Send the latest state to that key whenever the data changes.

  • The first PUT starts the Live Activity.
  • The next PUT request with the same stream_key updates it.
  • DELETE ends the Live Activity when the work is done.

What is a stream_key?#

A stream_key is a stable name for one ongoing process.

Examples:

  • prod-web-1
  • deployment-main
  • nightly-backup
  • ev-charging

Use one stream_key for one system, workflow, or process.

The same stream mechanism works with all Live Activity types. See the API reference for available fields.

Start Live Activity#

Send the initial state to prod-web-1. The first PUT starts a Metrics Live Activity.

curl -X PUT https://activitysmith.com/api/live-activity/stream/prod-web-1 \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content_state": {
"title": "Server Health",
"subtitle": "prod-web-1",
"type": "metrics",
"metrics": [
{
"label": "CPU",
"value": 24,
"unit": "%"
},
{
"label": "MEM",
"value": 61,
"unit": "%"
}
]
}
}'

Update Live Activity#

Send the latest state to the same stream_key. This updates the existing Live Activity with new CPU and memory values.

curl -X PUT https://activitysmith.com/api/live-activity/stream/prod-web-1 \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content_state": {
"title": "Server Health",
"subtitle": "prod-web-1",
"type": "metrics",
"metrics": [
{
"label": "CPU",
"value": 42,
"unit": "%"
},
{
"label": "MEM",
"value": 68,
"unit": "%"
}
]
}
}'

End Live Activity#

Use DELETE /live-activity/stream/:stream_key when the tracked process is finished and you want to dismiss the Live Activity. You can include final values before it is removed. By default, iOS removes the Live Activity after two minutes. Set auto_dismiss_minutes to choose a different dismissal time, including 0 for immediate dismissal.

curl -X DELETE https://activitysmith.com/api/live-activity/stream/prod-web-1 \
-H "Authorization: Bearer $YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content_state": {
"title": "Server Health",
"subtitle": "prod-web-1",
"type": "metrics",
"metrics": [
{
"label": "CPU",
"value": 7,
"unit": "%"
},
{
"label": "MEM",
"value": 38,
"unit": "%"
}
],
"auto_dismiss_minutes": 2
}
}'

content_state is optional here. Include it if you want one last update before the Live Activity is dismissed.

The response includes delivered. When it is false, no device received the end and a warning explains why. The Live Activity can then stay on the Lock Screen until iOS removes it or someone dismisses it.

If you later send another PUT request with the same stream_key, ActivitySmith starts a new Live Activity.

Stream responses#

Stream responses include an operation field:

  • started: ActivitySmith started a new Live Activity for this stream_key
  • updated: ActivitySmith updated the current Live Activity
  • rotated: ActivitySmith ended the current Live Activity and started a new one, for example because content_state.type or the target channels changed
  • noop: the incoming state matched the current state, so no update was sent
  • ended: returned by DELETE /live-activity/stream/:stream_key

updated responses also include a warning when this Live Activity is updating often enough that iOS may throttle it.

Update frequency and iOS limits#

8-hour limit#

iOS ends every Live Activity 8 hours after it starts and keeps it on the Lock Screen for up to 4 more hours. Once iOS ends it, no update or end can reach it.

To keep long-running streams reachable, ActivitySmith replaces a stream's Live Activity with a new one shortly before the 8-hour mark. The new Live Activity keeps the latest content, actions, Tags, and Metadata, and the stream_key stays the same, so later updates and the end work as usual. The stream's activity_id changes to the new Live Activity. Replacement only applies to streams that received a request in the last 24 hours, and it is not billed.