> ## Documentation Index
> Fetch the complete documentation index at: https://activitysmith.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Update Live Activity

> Legacy manual lifecycle endpoint. For new integrations, use PUT /live-activity/stream/{stream_key} so ActivitySmith can manage start, update, rotation, and end state for you. This endpoint remains supported for existing integrations and advanced lifecycle control. Updates an existing Live Activity. If the per-activity token is not registered yet, the update is queued. Supports segmented_progress, progress, metrics, stats, alert, and timer activity types. For segmented_progress activities, you can increase or decrease number_of_steps here as the workflow changes. For timer activities, send duration_seconds only when you want to reset the timer window; omit it to keep the current timer running. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities.

Use this manual lifecycle endpoint only when you need direct control over a
specific Live Activity instance. For new integrations, prefer
[`PUT /live-activity/stream/{stream_key}`](/docs/api-reference/endpoint/live-activity-stream).

This endpoint updates an existing Live Activity by `activity_id`.

* `metrics`: send the latest `metrics` array.
* `stats`: send the latest `metrics` array for up to 8 labeled values.
* `segmented_progress`: send the latest `current_step` and, if needed, an updated `number_of_steps`.
* `progress`: send the latest `percentage`, or `value` with `upper_limit`.
* `timer`: update visible fields such as `title`, `subtitle`, or `color`. Leave `duration_seconds` out unless you want to change the timer.
* `action` is optional if you want to set or replace the Live Activity button.
* `type` is optional on update if the existing Live Activity already has a type.

For `segmented_progress`, you can update both `current_step` and
`number_of_steps`. Use this when the workflow gains or loses steps after the
activity has already started.


## OpenAPI

````yaml POST /live-activity/update
openapi: 3.1.0
info:
  title: ActivitySmith API
  description: >-
    Send push notifications and Live Activities to your own devices via a single
    API key.
  version: 1.0.0
servers:
  - url: https://activitysmith.com/api
security:
  - apiKeyAuth: []
tags:
  - name: PushNotifications
    description: Send push notifications to paired devices.
  - name: AppIconBadges
    description: Update App Icon Badge Counts on paired devices.
  - name: LiveActivities
    description: Start, update, stream, and end Live Activities.
  - name: Metrics
    description: Update metric values shown in ActivitySmith widgets.
paths:
  /live-activity/update:
    post:
      tags:
        - LiveActivities
      summary: Update a Live Activity (legacy manual lifecycle)
      description: >-
        Legacy manual lifecycle endpoint. For new integrations, use PUT
        /live-activity/stream/{stream_key} so ActivitySmith can manage start,
        update, rotation, and end state for you. This endpoint remains supported
        for existing integrations and advanced lifecycle control. Updates an
        existing Live Activity. If the per-activity token is not registered yet,
        the update is queued. Supports segmented_progress, progress, metrics,
        stats, alert, and timer activity types. For segmented_progress
        activities, you can increase or decrease number_of_steps here as the
        workflow changes. For timer activities, send duration_seconds only when
        you want to reset the timer window; omit it to keep the current timer
        running. Use secondary_action for a second button on alert, progress,
        and segmented_progress Live Activities.
      operationId: updateLiveActivity
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LiveActivityUpdateRequest'
            examples:
              segmented_progress:
                value:
                  activity_id: pLAr-Hnq9ZFW4sxlk43Lhbuok4GLh7UW
                  content_state:
                    title: Nightly database backup
                    subtitle: upload archive
                    number_of_steps: 3
                    current_step: 2
              progress:
                value:
                  activity_id: pLAr-Hnq9ZFW4sxlk43Lhbuok4GLh7UW
                  content_state:
                    title: EV Charging
                    subtitle: Added 120 mi range
                    percentage: 60
              metrics:
                value:
                  activity_id: pLAr-Hnq9ZFW4sxlk43Lhbuok4GLh7UW
                  content_state:
                    title: Server Health
                    subtitle: prod-web-1
                    type: metrics
                    metrics:
                      - label: CPU
                        value: 25
                        unit: '%'
                      - label: MEM
                        value: 67
                        unit: '%'
              webhook_action:
                value:
                  activity_id: pLAr-Hnq9ZFW4sxlk43Lhbuok4GLh7UW
                  content_state:
                    title: Reindexing product search
                    subtitle: Shard 7 of 12
                    number_of_steps: 12
                    current_step: 7
                  action:
                    title: Pause Reindex
                    type: webhook
                    url: https://ops.example.com/hooks/search/reindex/pause
                    method: POST
                    body:
                      job_id: reindex-2026-03-19
                      requested_by: activitysmith_live_activity
                      reason: paused_from_ios_live_activity
              timer_preserve_window:
                value:
                  activity_id: pLAr-Hnq9ZFW4sxlk43Lhbuok4GLh7UW
                  content_state:
                    title: Benchmark Run
                    subtitle: checking p95 latency
                    type: timer
              timer_reset_window:
                value:
                  activity_id: pLAr-Hnq9ZFW4sxlk43Lhbuok4GLh7UW
                  content_state:
                    title: Benchmark Run
                    subtitle: retrying sample
                    type: timer
                    duration_seconds: 180
      responses:
        '200':
          description: Live Activity updated (or queued)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LiveActivityUpdateResponse'
              examples:
                sent:
                  value:
                    success: true
                    activity_id: pLAr-Hnq9ZFW4sxlk43Lhbuok4GLh7UW
                    devices_notified: 2
                    devices_queued: 0
                    timestamp: '2026-01-28T09:57:26.056Z'
        '403':
          description: Forbidden (activity not owned by this API key account)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'
              examples:
                forbidden:
                  value:
                    error: Forbidden
                    message: This API key cannot update this Live Activity
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RateLimitError'
              examples:
                rate_limited:
                  value:
                    error: Rate limit exceeded
                    message: Too many requests, please try again later.
      x-codeSamples:
        - lang: javascript
          label: Node
          source: |-
            import ActivitySmith from "activitysmith";

            const activitysmith = new ActivitySmith({
              apiKey: process.env.ACTIVITYSMITH_API_KEY,
            });

            await activitysmith.liveActivities.update({
              activity_id: "pLAr-Hnq9ZFW4sxlk43Lhbuok4GLh7UW",
              content_state: {
                title: "Nightly database backup",
                subtitle: "upload archive",
                number_of_steps: 3,
                current_step: 2,
              },
            });
        - lang: python
          label: Python
          source: >-
            import os

            from activitysmith import ActivitySmith


            activitysmith =
            ActivitySmith(api_key=os.environ["ACTIVITYSMITH_API_KEY"])


            activitysmith.live_activities.update({
                "activity_id": "pLAr-Hnq9ZFW4sxlk43Lhbuok4GLh7UW",
                "content_state": {
                    "title": "Nightly database backup",
                    "subtitle": "upload archive",
                    "number_of_steps": 3,
                    "current_step": 2,
                },
            })
        - lang: go
          label: Go
          source: "package main\n\nimport (\n\t\"log\"\n\n\tactivitysmithsdk \"github.com/ActivitySmithHQ/activitysmith-go\"\n)\n\nfunc main() {\n\tactivitysmith, err := activitysmithsdk.New(\"YOUR-API-KEY\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t_, err = activitysmith.LiveActivities.Update(activitysmithsdk.LiveActivityUpdateInput{\n\t\tActivityID:    \"pLAr-Hnq9ZFW4sxlk43Lhbuok4GLh7UW\",\n\t\tTitle:         \"Nightly database backup\",\n\t\tSubtitle:      \"upload archive\",\n\t\tNumberOfSteps: 3,\n\t\tCurrentStep:   2,\n\t})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n}"
        - lang: php
          label: PHP
          source: |-
            <?php

            use ActivitySmith\ActivitySmith;

            $activitysmith = new ActivitySmith($_ENV['ACTIVITYSMITH_API_KEY']);

            $activitysmith->liveActivities->update([
                'activity_id' => 'pLAr-Hnq9ZFW4sxlk43Lhbuok4GLh7UW',
                'content_state' => [
                    'title' => 'Nightly database backup',
                    'subtitle' => 'upload archive',
                    'number_of_steps' => 3,
                    'current_step' => 2,
                ],
            ]);
        - lang: ruby
          label: Ruby
          source: >-
            require "activitysmith"


            activitysmith = ActivitySmith::Client.new(api_key:
            ENV.fetch("ACTIVITYSMITH_API_KEY"))


            activitysmith.live_activities.update(
              activity_id: "pLAr-Hnq9ZFW4sxlk43Lhbuok4GLh7UW",
              content_state: {
                title: "Nightly database backup",
                subtitle: "upload archive",
                number_of_steps: 3,
                current_step: 2
              }
            )
        - lang: bash
          label: cURL
          source: |-
            curl -X POST "https://activitysmith.com/api/live-activity/update" \
              -H "Authorization: Bearer $ACTIVITYSMITH_API_KEY" \
              -H "Content-Type: application/json" \
              -d '{
                "activity_id": "pLAr-Hnq9ZFW4sxlk43Lhbuok4GLh7UW",
                "content_state": {
                  "title": "Nightly database backup",
                  "subtitle": "upload archive",
                  "number_of_steps": 3,
                  "current_step": 2
                }
              }'
components:
  schemas:
    LiveActivityUpdateRequest:
      type: object
      description: Update an existing Live Activity by activity_id.
      required:
        - activity_id
        - content_state
      properties:
        activity_id:
          type: string
        content_state:
          $ref: '#/components/schemas/ContentStateUpdate'
        action:
          $ref: '#/components/schemas/LiveActivityAction'
        secondary_action:
          $ref: '#/components/schemas/LiveActivityAction'
          description: >-
            Optional secondary action button. Supported for alert, progress, and
            segmented_progress Live Activities. Uses the same open_url,
            shortcuts://, and webhook shapes as action.
      additionalProperties: false
    LiveActivityUpdateResponse:
      type: object
      description: Returned after a Live Activity update is sent or queued.
      properties:
        success:
          type: boolean
        activity_id:
          type: string
        devices_queued:
          type: integer
        devices_notified:
          type: integer
        timestamp:
          type: string
          format: date-time
      required:
        - success
        - activity_id
        - timestamp
      additionalProperties: false
    ForbiddenError:
      type: object
      properties:
        error:
          type: string
        message:
          type: string
      required:
        - error
        - message
      additionalProperties: true
    RateLimitError:
      type: object
      properties:
        error:
          type: string
        message:
          type: string
      required:
        - error
        - message
      additionalProperties: false
    ContentStateUpdate:
      type: object
      description: >-
        Update payload requires title. For segmented_progress include
        current_step and optionally number_of_steps. For progress include
        percentage or value with upper_limit. For metrics and stats include a
        non-empty metrics array. For alert include message. For timer, omit
        duration_seconds to preserve the current timer window or send
        duration_seconds to reset the timer from the update request time.
        Optional icon is supported by all Live Activity types. Optional badge is
        supported by alert, progress, and segmented_progress. Type is optional
        when updating an existing activity. You can increase or decrease
        number_of_steps during updates.
      required:
        - title
      properties:
        title:
          type: string
        subtitle:
          type: string
        number_of_steps:
          type: integer
          minimum: 1
          description: >-
            Total number of steps. Use for type=segmented_progress. Optional on
            update, and safe to change if the workflow gains or loses steps.
        current_step:
          type: integer
          minimum: 0
          description: >-
            Current completed step count. Use for type=segmented_progress. Set 0
            when no segment is complete yet. Must be less than or equal to
            number_of_steps when number_of_steps is provided.
        percentage:
          type: number
          minimum: 0
          maximum: 100
          description: >-
            Progress percentage (0–100). Use for type=progress. Takes precedence
            over value/upper_limit if both are provided.
        value:
          type: number
          description: Current progress value. Use with upper_limit for type=progress.
        upper_limit:
          type: number
          exclusiveMinimum: 0
          description: Maximum progress value. Use with value for type=progress.
        duration_seconds:
          type: number
          exclusiveMinimum: 0
          description: >-
            Timer duration in seconds. For type=timer, sending duration_seconds
            resets the timer window from the update request time; omit it to
            preserve the existing timer window.
        counts_down:
          type: boolean
          default: true
          description: >-
            Use with type=timer. When true or omitted, the timer counts down
            from duration_seconds. Set false for an elapsed timer; omit
            duration_seconds for an open-ended elapsed timer.
        is_running:
          type: boolean
          default: true
          description: >-
            Use with type=timer. Defaults to true. Set false to pause/freeze via
            API; set true on a paused timer to resume.
        metrics:
          type: array
          description: Use for type=metrics or type=stats.
          minItems: 1
          maxItems: 8
          items:
            $ref: '#/components/schemas/ActivityMetric'
        message:
          type: string
          minLength: 1
          description: Alert message. Use for type=alert.
        icon:
          $ref: '#/components/schemas/LiveActivityAlertIcon'
          description: >-
            Optional SF Symbol icon. Supported by alert, progress,
            segmented_progress, metrics, stats, and timer.
        badge:
          $ref: '#/components/schemas/LiveActivityAlertBadge'
          description: >-
            Optional badge. Supported by alert, progress, and
            segmented_progress.
        type:
          type: string
          enum:
            - segmented_progress
            - progress
            - metrics
            - stats
            - alert
            - timer
          description: >-
            Optional. When omitted, the API uses the existing Live Activity
            type.
        color:
          type: string
          enum:
            - lime
            - green
            - cyan
            - blue
            - purple
            - magenta
            - red
            - orange
            - yellow
            - gray
          description: >-
            Optional. Accent color for progress, segmented_progress, metrics,
            and timer Live Activities. For Alert Live Activities, this tints
            action and secondary_action buttons when included.
        step_color:
          type: string
          enum:
            - lime
            - green
            - cyan
            - blue
            - purple
            - magenta
            - red
            - orange
            - yellow
            - gray
          description: >-
            Optional. Overrides color for the current step. Only applies to
            type=segmented_progress.
        step_colors:
          type: array
          items:
            type: string
            enum:
              - lime
              - green
              - cyan
              - blue
              - purple
              - magenta
              - red
              - orange
              - yellow
              - gray
          description: >-
            Optional. Colors for completed steps. When used with
            segmented_progress, the array length should match current_step.
      dependentRequired:
        value:
          - upper_limit
        upper_limit:
          - value
      additionalProperties: false
    LiveActivityAction:
      type: object
      description: >-
        Optional action button shown in the Live Activity UI. Use action for the
        primary button, or secondary_action for a secondary button on alert,
        progress, and segmented_progress Live Activities.
      properties:
        title:
          type: string
          description: Button title displayed in the Live Activity UI.
        type:
          $ref: '#/components/schemas/LiveActivityActionType'
        url:
          type: string
          format: uri
          description: >-
            Action URL. For open_url, use an HTTP or HTTPS URL or a
            shortcuts://run-shortcut?name=... URL that runs a specific iPhone
            Shortcut. For webhook, use an HTTPS URL called by the ActivitySmith
            backend.
        method:
          $ref: '#/components/schemas/LiveActivityWebhookMethod'
          description: Webhook HTTP method. Used only when type=webhook.
        body:
          type: object
          additionalProperties: true
          description: Optional webhook payload body. Used only when type=webhook.
      required:
        - title
        - type
        - url
      allOf:
        - if:
            properties:
              type:
                const: open_url
            required:
              - type
          then:
            properties:
              url:
                pattern: ^(http|https|shortcuts)://
        - if:
            properties:
              type:
                const: webhook
            required:
              - type
          then:
            properties:
              url:
                pattern: ^https://
      additionalProperties: false
    ActivityMetric:
      type: object
      required:
        - label
        - value
      properties:
        label:
          type: string
          minLength: 1
        value:
          oneOf:
            - type: number
              minimum: 0
            - type: string
              minLength: 1
              maxLength: 64
        unit:
          type: string
        color:
          type: string
          enum:
            - lime
            - green
            - cyan
            - blue
            - purple
            - magenta
            - red
            - orange
            - yellow
            - gray
          description: Optional per-metric accent color for metrics and stats activities.
      additionalProperties: false
    LiveActivityAlertIcon:
      type: object
      description: Optional SF Symbol icon for Live Activities.
      required:
        - symbol
      properties:
        symbol:
          type: string
          minLength: 1
          description: Apple SF Symbol name.
        color:
          $ref: '#/components/schemas/LiveActivityColor'
          description: Optional icon color.
      additionalProperties: false
    LiveActivityAlertBadge:
      type: object
      description: Optional badge for Live Activities.
      required:
        - title
      properties:
        title:
          type: string
          minLength: 1
        color:
          $ref: '#/components/schemas/LiveActivityColor'
          description: Optional badge color.
      additionalProperties: false
    LiveActivityActionType:
      type: string
      enum:
        - open_url
        - webhook
    LiveActivityWebhookMethod:
      type: string
      enum:
        - GET
        - POST
      default: POST
    LiveActivityColor:
      type: string
      enum:
        - lime
        - green
        - cyan
        - blue
        - purple
        - magenta
        - red
        - orange
        - yellow
        - gray
  securitySchemes:
    apiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key
      description: >-
        Required. Include `Authorization: Bearer ask_123456789` in every
        request. Replace `ask_123456789` with your API key.

````