Update a Live Activity

Updates the content of a running Live Activity, or ends it.

Use this endpoint to update the content of a running Live Activity, or to end it.

API at a glance

Description: Updates change the card in place rather than sending a fresh notification each time, so customers see the latest state without a stream of alerts building up. Use the same endpoint to end an activity by setting end_activity to true.

Address the activity with the bsft_activity_id you set as bsftActivityId when calling Start a Live Activity, together with the same activity_attributes_type. Both must match or the activity is not found.

Before you can use this endpoint

App setup

Live Activities must be built into your iOS app and integrated with the Blueshift iOS SDK before this endpoint can deliver anything. Your app defines the layout of the card and the content it accepts. Blueshift sends the content that appears inside it.

For setup instructions, see Set up Live Activities.

Requirements

  • Devices running iOS 17.2 or later
  • Blueshift iOS SDK 2.8.0 or later
  • Token-based (.p8) push authentication configured on your Blueshift push adapter
  • An activity already started with Start a Live Activity

Authentication & testing - Live Activities

Testing the API on this page

How to try it here

  • Use your Event API Key as the Username (leave Password blank). You can find it in the Blueshift app under Account Settings > API Keys.
  • Select the appropriate API endpoint based on your Blueshift region.
  • API - Select Region
  • Enter the necessary parameters and click Try It to run the request.
Authentication using Base64 encoding

Note for developers

API requests require authentication using HTTP Basic Authentication with the Event API Key. The Event API Key serves as the username, while the password field should be left empty. The format to encode is: your\_api\_key: (note the trailing colon).

This string must be Base64-encoded and included in the request's Authorization header as follows:

Authorization: Basic encoded\_value

You can generate the encoded value using a trusted Base64 encoder.


Postman collection

Try it with Postman: Explore the API using Blueshift's Postman collection.


Things to know before you start

  • bsft_activity_id and activity_attributes_type must both match the values used to start the activity. If either differs, the activity is not found and nothing is delivered.
  • Retry an update that returns Running Live Activity not found for any device. The device registers the activity with Blueshift shortly after it starts. An update sent before that completes returns this message. It is not a permanent failure.
  • content_state property names must match your app. They must exactly match the ContentState your app defines. A mismatch is not reported as an error: the API returns a success response and the device discards the content.
  • Omit notification to update silently. Include it only when a change is significant enough to alert the customer.
  • Set end_activity to true to end the activity. It is removed from the Dynamic Island immediately and clears from the Lock Screen shortly after.
  • Activities can be updated for up to 8 hours after they start. This is an Apple limit. For events that run longer, end the activity and start a new one for each stage.
  • A 200 response means the push was dispatched, not displayed. Check dispatched_to and the errors array in the response.

Request parameters

Check out the request parameters

Body parameters

ParameterTypeRequiredDescription
customer_identifier_typestring✅ YesType of identifier used in customer_identifiers. One of customer_id, email, or phone_number.
customer_identifiersstring[]✅ YesIdentifier values. Maximum 50 per call.
activity_attributes_typestring✅ YesName of the activity design. Must match the value used when starting the activity.
bsft_activity_idstring✅ YesThe identifier you set as bsftActivityId when starting the activity.
content_stateobject✅ YesUpdated dynamic content. Property names must match the ContentState defined in your app.
notificationobject❌ NoAlert shown with the update. Accepts title and body. Omit it to update the activity silently.
end_activityboolean❌ NoSet to true to end the activity. Defaults to false.
stale_datestring❌ NoISO 8601 timestamp after which the content is considered out of date.
dismissal_datestring❌ NoISO 8601 timestamp at which the activity is dismissed from the device.

Example requests & responses

Update an activity
  curl --request POST \
       --url https://api.getblueshift.com/api/v1/live_activity/update \
       --header 'accept: application/json' \
       --header 'authorization: Basic YWNlZDZlNGYxMWExYWVhOTZmNTJkNDg4M2ZmMjI4Mjg6' \
       --header 'content-type: application/json' \
       --data '
  {
    "customer_identifier_type": "email",
    "customer_identifiers": ["[email protected]"],
    "activity_attributes_type": "DeliveryActivityAttribute",
    "bsft_activity_id": "order_4482",
    "content_state": {
      "title": "Out for delivery",
      "subtitle": "Arriving by 6:45 PM",
      "progress": 0.7
    }
  }
  '
{
  "status": "ok",
  "dispatched_to": 1,
  "errors": []
}
End an activity

Set end_activity to true. The content_state you send is the final content the customer sees before the card clears.

  curl --request POST \
       --url https://api.getblueshift.com/api/v1/live_activity/update \
       --header 'accept: application/json' \
       --header 'authorization: Basic YWNlZDZlNGYxMWExYWVhOTZmNTJkNDg4M2ZmMjI4Mjg6' \
       --header 'content-type: application/json' \
       --data '
  {
    "customer_identifier_type": "email",
    "customer_identifiers": ["[email protected]"],
    "activity_attributes_type": "DeliveryActivityAttribute",
    "bsft_activity_id": "order_4482",
    "content_state": {
      "title": "Delivered",
      "subtitle": "Enjoy your order",
      "progress": 1.0
    },
    "end_activity": true
  }
  '
{
  "status": "ok",
  "dispatched_to": 1,
  "errors": []
}
Response when the activity is not found

The request succeeds with a 200 status, but dispatched_to is 0 and the errors array explains why. This happens when the activity has already ended, the customer dismissed it, or the device has not finished registering it.

{
  "status": "ok",
  "dispatched_to": 0,
  "errors": [
    {
      "customer_identifier_type": "email",
      "customer_identifier_value": "[email protected]",
      "error_message": "Running Live Activity not found for any device"
    }
  ]
}
API error responses
Status codeDescriptionExample response
400 Bad RequestA required parameter is missing or malformed.{ "errors": [{ "detail": "Missing customer_identifier_type" }] }
401 UnauthorizedAPI authentication failed due to an invalid or missing API key.{ "message": "Not authorized" }
403 ForbiddenThe API key does not have sufficient permissions.{ "message": "Forbidden" }
404 Not FoundNone of the supplied identifiers resolved to a customer.{ "errors": [{ "detail": "No identifiers resolved" }] }
413 Payload Too LargeMore than 50 customer identifiers were supplied.{ "errors": [{ "detail": "You can add maximum 50 customer identifiers in one API call" }] }
422 Unprocessable EntityThe account has no push adapter configured.{ "errors": [{ "detail": "No push adapter configured" }] }
429 Too Many RequestsThe request limit has been exceeded.{ "message": "Rate limit exceeded" }
500 Internal Server ErrorAn unexpected server error occurred.{ "errors": [{ "detail": "Delivery failed" }] }
502 Bad GatewayThe server received an invalid response. Retry with exponential backoff.{ "message": "Bad Gateway" }
503 Service UnavailableThe service is temporarily unavailable. Retry with exponential backoff.{ "message": "Service Unavailable" }
504 Gateway TimeoutThe server took too long to respond. Retry with exponential backoff.{ "message": "Gateway Timeout" }

Field reference

Response fields
FieldTypeDescription
statusstringResult of the request. Returns ok when the request was accepted.
dispatched_tointegerNumber of devices the message was dispatched to. A value of 0 means no device received it; check the errors array.
errorsarrayPer-identifier errors. Empty when every identifier resolved to a device.
errors[].customer_identifier_typestringThe identifier type supplied in the request.
errors[].customer_identifier_valuestringThe identifier value that could not be reached.
errors[].error_messagestringWhy the identifier could not be reached.
Error messages in the errors array
MessageDescription
Running Live Activity not found for any deviceNo running activity matches this bsft_activity_id and activity_attributes_type. The activity may have ended, been dismissed by the customer, or not yet finished registering.
No user found for given identifierNo customer matches the identifier supplied.

Body Params
string
enum
required

Type of identifier used in customer_identifiers.

Allowed:
customer_identifiers
array of strings
required

Identifier values. Maximum 50 per call.

customer_identifiers*
string
required

Name of the activity design, matching the name your app registers with registerPushToStart.

string
required

The identifier you set as bsftActivityId when starting the activity.

content_state
object
required

Updated dynamic content. The property names must exactly match the ContentState defined in your app.

notification
object

Optional alert shown with the update. Omit it to update the activity silently.

boolean

Set to true to end the activity. The activity is removed from the Dynamic Island immediately and clears from the Lock Screen shortly after.

date-time

ISO 8601 timestamp after which the content is considered out of date.

date-time

ISO 8601 timestamp at which the activity is dismissed from the device.

Responses

429

Rate limit exceeded - Too many requests

502

Service unavailable, please retry - Bad Gateway, re-try with exponential backoff

503

Service unavailable, please retry - Service Unavailable, re-try with exponential backoff

504

Service unavailable, please retry - Gateway Timeout, please re-try with exponential backoff

Language
Credentials
Basic
base64
:
URL
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
application/json