# API Keys Source: https://activitysmith.com/docs/api-keys Create and manage API keys API Keys are secret tokens used to authenticate your requests. They are unique to your account and should be kept confidential. ## Create an API Key To create an API key, go to the [API Keys](https://activitysmith.com/app/keys) page and click the **Create API Key** button. 1. Click **Create API Key**. 2. Give your API Key a name (maximum 100 characters). 3. Select **All Recipients** or **Channel Scoped** as the Scope. 4. If you select **Channel Scoped**, you can choose the channels you want to restrict access to. Create API Key For security reasons, you can only view the API Key once. ## API Key Scopes There are two different API Key Scopes you can choose from: * **All Recipients**: The API key can target all recipients in the account. * **Channel Scoped**: The API key is restricted to channels assigned to that key. API Key Scopes You can configure scope when creating or editing a key on the [API Keys](https://activitysmith.com/app/keys) page. ## Edit API Key details After creating an API Key, you can edit the following details: * Name * Scope * Scope Channels (only available if Scope is **Channel Scoped**) To edit an API Key, click the **Edit API Key** button. ## View all API Keys To manage your API keys, go to the [API Keys](https://activitysmith.com/app/keys) page. The page shows you all the API Keys you have created along with their details View API Keys ## Scope behavior with `target.channels` * Scope `all` + no `target.channels`: sends to all recipients in your account. * Scope `all` + `target.channels`: sends only to the provided channel slugs. * Scope `channels` + no `target.channels`: sends to channels assigned to that API key. * Scope `channels` + `target.channels`: requested channel slugs must be a subset of channels assigned to that API key. Channels in request payloads use channel slugs, for example, `["marketing", "test-devices"]`. ## Scope enforcement and errors If a channel-scoped key (`channels`) tries to target channel slugs outside its assignment, the request fails with `403 Forbidden` and a clear scope-violation error message. Use the [channels guide](/docs/channels) for channel setup and targeting examples. # End Live Activity Source: https://activitysmith.com/docs/api-reference/endpoint/live-activity-end POST /live-activity/end Legacy manual lifecycle endpoint. For new integrations, use DELETE /live-activity/stream/{stream_key} to end a managed Live Activity stream. This endpoint remains supported for existing integrations and advanced lifecycle control. Ends a Live Activity and archives its lifecycle. Supports segmented_progress, progress, metrics, stats, alert, and timer activity types. For segmented_progress activities, you can send the latest number_of_steps here if the workflow changed after start. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities only. Use this manual lifecycle endpoint only when you need direct control over a specific Live Activity instance. For new integrations, prefer [`DELETE /live-activity/stream/{stream_key}`](/docs/api-reference/endpoint/live-activity-stream). This endpoint ends an existing Live Activity by `activity_id`. * `metrics`: send the final `metrics` array if you want the ended state to show final values. * `stats`: send the final `metrics` array if you want the ended state to show final labeled values. * `segmented_progress`: send the final `current_step` and optionally the latest `number_of_steps`. * `progress`: send the final `percentage`, or `value` with `upper_limit`. * `timer`: leave `duration_seconds` out if you want the ended state to preserve the current timer value. * `action` is optional if you want the ended state to keep showing a button before dismissal. * `auto_dismiss_minutes` is optional if you want to control how long the ended Live Activity stays visible. For `segmented_progress`, the final payload can include an updated `number_of_steps` as well as the final `current_step`. The step count does not need to match the value used when the activity started. # Start Live Activity Source: https://activitysmith.com/docs/api-reference/endpoint/live-activity-start POST /live-activity/start 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. Starts a Live Activity on devices matched by API key scope and optional target channels. Supports segmented_progress, progress, metrics, stats, alert, and timer activity types. For segmented_progress activities, number_of_steps can be changed later during update or end calls if the workflow changes. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities only. 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 creates a new Live Activity and returns an `activity_id`. You will use that same ID for later update and end calls. * `metrics`: send `title`, `type`, and a non-empty `metrics` array. * `stats`: send `title`, `type`, and a non-empty `metrics` array for up to 8 labeled values. * `segmented_progress`: send `title`, `type`, `number_of_steps`, and `current_step`. * `progress`: send `title`, `type`, and either `percentage` or `value` with `upper_limit`. * `timer`: send `title`, `type`, and `duration_seconds` for a countdown. To start at 00:00 and count up, set `counts_down` to `false` and leave out `duration_seconds`. * `action` is optional if you want the Live Activity to show one button that opens a URL or triggers a webhook. * `target.channels` is optional if you want to scope delivery to specific channel slugs. For `segmented_progress`, `number_of_steps` is not fixed for the full lifecycle. You can change it later in update or end calls if the workflow adds or removes steps. # Live Activity Stream Source: https://activitysmith.com/docs/api-reference/endpoint/live-activity-stream PUT /live-activity/stream/{stream_key} Use a stable stream_key for each ongoing thing you want to show as a Live Activity. Send the latest content_state whenever it changes, and ActivitySmith will keep the Live Activity in sync. For timer streams, send duration_seconds to start or reset the timer; omit duration_seconds on later updates to preserve the existing timer window. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities only. Use this endpoint when you want ActivitySmith to manage the Live Activity for you. * Send the latest state for a stable `stream_key`. * If the Live Activity does not exist yet, ActivitySmith starts it. * If it already exists, ActivitySmith updates it. * You do not need to keep local state between updates. * For `timer`, send `duration_seconds` for countdowns. To start at 00:00 and count up, set `counts_down` to `false` and leave out `duration_seconds`. * Later `timer` updates can change visible fields without sending `duration_seconds`. This is a good fit for cron jobs, scheduled tasks, CI workflows, monitoring jobs, and background workers that only know the latest state. To stop a managed stream, use [`DELETE /live-activity/stream/{stream_key}`](/docs/api-reference/endpoint/live-activity-stream-end). # End Live Activity Stream Source: https://activitysmith.com/docs/api-reference/endpoint/live-activity-stream-end DELETE /live-activity/stream/{stream_key} Use this endpoint when the process you are tracking is finished and you no longer want the Live Activity on your devices. ActivitySmith ends the current Live Activity for this stream and dismisses it from devices. If you need direct lifecycle control, use /live-activity/start, /live-activity/update, and /live-activity/end instead. Use secondary_action for a second button on alert, progress, and segmented_progress Live Activities only. Use this endpoint when the process you are tracking is finished and you want to dismiss the managed Live Activity stream. * Call it with the same `stream_key` you used for stream updates. * You can include optional `content_state` with final values. * 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. # Update Live Activity Source: https://activitysmith.com/docs/api-reference/endpoint/live-activity-update POST /live-activity/update 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 only. 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. # Update Metric Value Source: https://activitysmith.com/docs/api-reference/endpoint/metric-value-update POST /metrics/{key}/value Updates the latest value for a metric displayed in ActivitySmith widgets. Create the metric in the web app first, then update its value using the key. # Send Push Notification Source: https://activitysmith.com/docs/api-reference/endpoint/push-notification POST /push-notification Sends a push notification to devices matched by API key scope and optional target channels. Supports optional redirection URL, optional media preview or playback when the notification is expanded, and up to 4 interactive actions. `media` cannot be combined with `actions`. # Introduction Source: https://activitysmith.com/docs/api-reference/introduction ActivitySmith API reference ## Features Send a push notification to all of your paired devices. Start, update, and dismiss a Live Activity stream. Update metric values shown in ActivitySmith widgets. ## Base URL All requests contain the following base URL: ```bash theme={null} https://activitysmith.com/api/ ``` ## Authentication For authentication, it's required to include an Authorization header. The header should contain `Bearer ask_123456789`, where `ask_123456789` represents your [API Key](/docs/api-keys). ```bash theme={null} Authorization: Bearer ask_123456789 ``` ## Response codes ActivitySmith employs conventional HTTP status codes to signify the outcome of your requests. Typically, 2xx HTTP status codes denote success, 4xx codes represent failures related to the user, and 5xx codes signal infrastructure problems. | Status | Description | | ------ | -------------------------------------------- | | 200 | Request was successful. | | 400 | Verify the correctness of the parameters. | | 401 | The API key is invalid or was not provided. | | 404 | The requested resource could not be located. | | 429 | The rate limit has been surpassed. | | 5xx | Signifies a server error with ActivitySmith. | Refer to the Error Codes section for a detailed explanation of all potential API errors. ## Channels Channels let you target specific subsets of recipients instead of broadcasting to everyone in an account. * Use channels when teams, environments, or workflows need separate delivery groups. * Keep [API keys](/docs/api-keys) broad or channel-scoped depending on how strict you want targeting to be. Read the full [channels guide](/docs/channels). ## Rate limit The ActivitySmith API has a [rate limit](/docs/rate-limits) to ensure the stability and reliability of the service. The rate limit is applied to all endpoints and is based on the number of requests made within a specific time frame. When you exceed the rate limit, you will receive a 429 response code. # Channels Source: https://activitysmith.com/docs/channels Use channels to target specific users and devices. Channels let you target specific groups of recipients instead of sending to everyone in an account. Common use case: * Different teams should receive different notifications (for example, `marketing`, `developers`, `devops`, `sre`). Channels are flexible: * You can assign users, devices, or both to a channel. * You can choose channels per request using `target.channels`. * You can keep some [API key](/docs/api-keys) broad and scope other [API key](/docs/api-keys) to specific channels. ## How Targeting Works Use channel slugs in `target.channels`: ```json theme={null} { "target": { "channels": ["ios-beta", "ops"] } } ``` * If `target` is omitted and API key scope is `all`, delivery goes to all recipients in the account. * If `target` is omitted and API key scope is `channels`, delivery goes to channels assigned to that [API key](/docs/api-keys). * If `target.channels` is provided, only those channel slugs are targeted. ## Push Notifications ```json theme={null} { "title": "New subscription 💸", "message": "Customer upgraded to Pro plan", "target": { "channels": ["ios-beta", "ops"] } } ``` ## Live Activities ```json theme={null} { "content_state": { "title": "Nightly database backup", "number_of_steps": 3, "current_step": 1, "type": "segmented_progress" }, "target": { "channels": ["ios-beta", "ops"] } } ``` See endpoint docs for full request and response fields: * [/api-reference/endpoint/push-notification](/docs/api-reference/endpoint/push-notification) * [/api-reference/endpoint/live-activity-start](/docs/api-reference/endpoint/live-activity-start) # Live Activity Colors Source: https://activitysmith.com/docs/colors Colors can be used to customize the appearance of your Live Activities. You can choose from the following colors(default is `blue`): ### `lime` Lime Live Activity ### `green` Green Live Activity ### `cyan` Cyan Live Activity ### `blue` Blue Live Activity ### `purple` Purple Live Activity ### `magenta` Magenta Live Activity ### `red` Red Live Activity ### `orange` Orange Live Activity ### `yellow` Yellow Live Activity # Inbound Webhooks Source: https://activitysmith.com/docs/inbound-webhooks Forward events from external services into Push Notifications and Live Activities. Inbound webhooks let an external service POST events to ActivitySmith. Each event is turned into a Push Notification or a Live Activity on the paired iOS devices you target, with no backend code on your side. Use inbound webhooks when you want lock-screen visibility into a service that already has its own webhook system, like CI runs, deploys, error alerts, or issue updates. Inbound webhook presets in the ActivitySmith dashboard ## How It Works 1. Generate an inbound webhook URL in the [Webhooks section](https://activitysmith.com/app/webhooks). 2. Paste it into the source service (GitHub, Vercel, Sentry, and so on) and pick the events you care about. 3. Choose how the event is delivered: Push Notification or Live Activity. 4. Map payload fields to the title, message, and metadata you want shown. 5. Optionally route the event to specific [channels](/docs/channels). Each integration ships with ready-to-use presets that cover the most common events, so you can connect a source in a few clicks. Tweak any field on a preset, or start from scratch when you want full control over the title, body, action button, etc. The same source service can drive multiple webhooks. For example, you can send production deploy events to a `#prod` channel as a Live Activity, and preview deploys to a `#previews` channel as a Push Notification. ## Delivery Options Each webhook delivers events as one of: * **Push Notification**: best for short, conclusive events like a check that failed, a PR that merged, or an alert that fired. * **Live Activity**: best for long-running work like CI workflows or production deploys. The Live Activity stays on the lock screen while the job runs and dismisses when it finishes. You can also attach an action button to the resulting notification or activity that opens the source service (the GitHub run, the Sentry issue, the Vercel deployment, and so on). See the [action button section](/docs/#action-button) on the quickstart for the field reference. ## Channel Routing Inbound webhooks use the same [channels](/docs/channels) as the rest of the API. Route events from a webhook to one or more channel slugs so they reach the right people or devices. ## Secret Verification ActivitySmith verifies inbound requests with a per-webhook secret. The source service must include the secret on every request as an HTTP header: ``` X-ActivitySmith-Webhook-Secret: YOUR_SECRET ``` Requests with a missing or wrong secret are rejected and logged in the delivery log so you can spot misconfigured sources. Some integrations (like GitHub and Linear) sign their payloads with their own scheme. ActivitySmith verifies those signatures natively when you use the integration, so you do not need a separate secret. ## Delivery Log Webhook delivery log in the ActivitySmith dashboard Every webhook keeps a rolling log of recent requests. For each entry you can see: * The raw incoming payload * The mapped Push Notification or Live Activity that was sent * Verification or mapping errors, if any Use the log to debug new integrations, confirm a noisy source has been quieted down, or replay a payload while you tweak the field mapping. ## Available Integrations Pre-built integrations handle event subscription, signature verification, and a default field mapping for you. You can override the mapping at any time. | Integration | Supported events | | ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | | [GitHub](https://activitysmith.com/integrations/github-webhooks) | [GitHub webhook events](https://docs.github.com/en/webhooks/webhook-events-and-payloads) | | [GitLab](https://activitysmith.com/integrations/gitlab) | [GitLab webhook events](https://docs.gitlab.com/user/project/integrations/webhook_events/) | | [Linear](https://activitysmith.com/integrations/linear) | [Linear webhook events](https://linear.app/developers/webhooks) | | [Sentry](https://activitysmith.com/integrations/sentry) | [Sentry webhook events](https://docs.sentry.io/organization/integrations/integration-platform/webhooks/) | | [Vercel](https://activitysmith.com/integrations/vercel) | [Vercel webhook events](https://vercel.com/docs/webhooks/webhooks-api) | | [Netlify](https://activitysmith.com/integrations/netlify) | [Netlify deploy notifications](https://docs.netlify.com/deploy/deploy-notifications/) | | [Railway](https://activitysmith.com/integrations/railway) | [Railway webhook events](https://docs.railway.com/guides/webhooks) | The full integration list with setup guides lives at [activitysmith.com/integrations](https://activitysmith.com/integrations). ## Generic JSON If the service you want to track is not on the list, use a generic JSON webhook. Send any JSON payload to your inbound URL, paste a sample into the dashboard, and map fields like `title`, `subtitle`, `body`, and `url` onto the resulting Push Notification or Live Activity. This works for internal services, cron jobs, or third-party tools that expose webhooks but do not have a dedicated ActivitySmith integration yet. Need an integration that is not listed? Email [adam@activitysmith.com](mailto:adam@activitysmith.com). # Quickstart Source: https://activitysmith.com/docs/index Send Live Activities and push notifications to your iOS devices from any backend
ActivitySmith Live Activities ActivitySmith Push Notifications
## Welcome to ActivitySmith [ActivitySmith](https://activitysmith.com) is API service that lets you trigger and update Live Activities and send push notifications directly from your own infrastructure. Pair your iOS device(s), authenticate with an [API key](/docs/api-keys), and send real-time alerts from any backend, cron, agent, or automation. Without building or maintaining your own iOS app or dealing directly with APNs. Check out the following resources to get started: * **API**: [Documentation](https://activitysmith.com/docs/api-reference/introduction) * **SDKs**: [Node](https://activitysmith.com/docs/sdks/node), [Python](https://activitysmith.com/docs/sdks/python), [Go](https://activitysmith.com/docs/sdks/go), [PHP](https://activitysmith.com/docs/sdks/php), [Ruby](https://activitysmith.com/docs/sdks/ruby), [CLI](https://activitysmith.com/docs/sdks/cli) * **Others**: [Zapier](https://zapier.com/apps/activitysmith/integrations) Want an SDK or Integration? Let us know at [adam@activitysmith.com](mailto:adam@activitysmith.com). ### Prerequisites * [Create an API key](https://activitysmith.com/app/keys) * [Download our iOS app](https://apps.apple.com/us/app/activitysmith/id6752254835) and pair your device(s) ### Features * [**Push Notifications**](#push-notifications): send push notifications to all paired devices or target specific channels. * [**Live Activities**](#live-activities): start, update and end a Live Activity on your lock screen or dynamic island, with optional channel targeting and one optional action button. * [**Widgets**](/docs/widgets): display any value on your Lock Screen with widgets - SaaS metrics, revenue, signups, uptime, habits, or anything else you want to track. * [**Inbound Webhooks**](/docs/inbound-webhooks): forward events from external services such as Vercel, Netlify, Railway, and more, into Push Notifications and Live Activities. ### Powerful Capabilities * **Glanceable observability**: monitor real-time system state and long-running operations directly on your lock screen or dynamic island. * **The hard stuff**: APNs(Apple Push Notification service), certificates, orchestration * **Customizability**: adapt the experience to fit your unique needs. * **Works with any backend**: use with any backend, cron, agent, automation or AI tool. * **iOS app**: ready to use native iOS app for your iPhone or iPad. No need to build your own. ## Push Notifications To send a push notification, use the `push-notification` endpoint. It takes `title` and optional fields like `message`, `payload`, `media`, `redirection`, `actions`, and `target.channels`.\ `target.channels` accepts channel slugs (for example `["devs", "ops"]`). * `media` attaches an image, audio file, or video that users can preview or play when they expand the notification. * `redirection` opens an HTTPS URL or runs a specific iPhone Shortcut with a `shortcuts://run-shortcut?name=...` URL on normal tap. * `actions` (up to 4) appear when users expand the notification. `open_url` actions support HTTPS URLs and `shortcuts://run-shortcut?name=...` URLs; `webhook` actions call your backend. * `media + redirection` is supported. * `media + actions` is not supported in v1. Push Notification ```bash cURL theme={null} curl -X POST https://activitysmith.com/api/push-notification \ -H "Authorization: Bearer $ACTIVITYSMITH_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "New subscription 💸", "message": "Customer upgraded to Pro plan" }' ``` ```js Node theme={null} import ActivitySmith from "activitysmith"; const activitysmith = new ActivitySmith({ apiKey: process.env.ACTIVITYSMITH_API_KEY, }); await activitysmith.notifications.send({ title: "New subscription 💸", message: "Customer upgraded to Pro plan", }); ``` ```python Python theme={null} import os from activitysmith import ActivitySmith activitysmith = ActivitySmith( api_key=os.environ.get("ACTIVITYSMITH_API_KEY", "YOUR-API-KEY") ) activitysmith.notifications.send( title="New subscription 💸", message="Customer upgraded to Pro plan", ) ``` ```go Go theme={null} package main import ( "log" "os" activitysmithsdk "github.com/ActivitySmithHQ/activitysmith-go" ) func main() { activitysmith, err := activitysmithsdk.New(os.Getenv("ACTIVITYSMITH_API_KEY")) if err != nil { log.Fatal(err) } input := activitysmithsdk.PushNotificationInput{ Title: "New subscription 💸", Message: "Customer upgraded to Pro plan", } _, err := activitysmith.Notifications.Send(input) if err != nil { log.Fatal(err) } } ``` ```php PHP theme={null} notifications->send( title: 'New subscription 💸', message: 'Customer upgraded to Pro plan', ); ``` ```ruby Ruby theme={null} require "activitysmith" activitysmith = ActivitySmith::Client.new( api_key: ENV.fetch("ACTIVITYSMITH_API_KEY", "YOUR-API-KEY") ) activitysmith.notifications.send( { title: "New subscription 💸", message: "Customer upgraded to Pro plan" } ) ``` ```bash CLI theme={null} activitysmith push \ --title "New subscription 💸" \ --message "Customer upgraded to Pro plan" ``` **Response** ```json theme={null} { "success": true, "devices_notified": 3, "users_notified": 1, "timestamp": "2025-08-12T12:00:00.000Z" } ``` ## Live Activities There are six types of Live Activities: | Type | Best for | Required state | | -------------------- | ----------------------------- | ------------------------------------------------------------------------------ | | `stats` | up to 8 labeled values | `title`, `type`, and a non-empty `metrics` array | | `metrics` | Live operational stats | `title`, `type`, and a non-empty `metrics` array | | `segmented_progress` | Jobs tracked in steps | `title`, `type`, `number_of_steps`, `current_step` | | `progress` | Jobs with continuous progress | `title`, `type`, and either `percentage` or `value` + `upper_limit` | | `alert` | Focused status updates | `title`, `type`, and `message` | | `timer` | Countdowns or elapsed runtime | `title`, `type`, and either `duration_seconds` or `counts_down` set to `false` | Stats Live Activity Metrics Live Activity update Progress Live Activity start Segmented Progress Live Activity update Alert Live Activity update Timer Live Activity update ### Start & Update Live Activity Use stream updates to start, update, and dismiss Live Activities with a stable `stream_key`. * [`PUT /live-activity/stream/:stream_key`](/docs/stream) * [`DELETE /live-activity/stream/:stream_key`](/docs/stream) Send the latest state for a stable `stream_key`, and ActivitySmith starts or updates the Live Activity. You do not need to keep local state between updates. When the work is done, call `DELETE /live-activity/stream/:stream_key` with the same `stream_key` 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. ### Action Button Live Activities support one optional `action` button shown on the Lock Screen. Use it to have a one-tap path from a long-running job to the place where you can act on it. The `action` field is accepted on stream updates and works with all Live Activity types. For `alert` Live Activities, set `content_state.color` to tint the action button. `icon.color` and `badge.color` only affect the icon and badge.
Live Activity with an action button on iPhone Metrics Live Activity with an action button
There are two action types: * `open_url`: opens an HTTPS URL or runs a specific iPhone Shortcut with a `shortcuts://run-shortcut?name=...` URL. * `webhook`: ActivitySmith's backend calls your HTTPS webhook with `GET` or `POST`. The `action` object accepts: | Field | Required | Description | | -------- | ------------ | -------------------------------------------------------------------------------------------------------------------- | | `title` | yes | Button label shown on the Live Activity. | | `type` | yes | Either `open_url` or `webhook`. | | `url` | yes | For `open_url`, use an HTTPS URL or a `shortcuts://run-shortcut?name=...` URL. For `webhook`, use an HTTPS endpoint. | | `method` | webhook only | `GET` or `POST`. | | `body` | webhook only | Optional JSON payload sent with the webhook request. | #### open\_url Use `open_url` when the button should jump the user to a dashboard or run page tied to the work. You can also use a `shortcuts://run-shortcut?name=...` URL to run a specific iPhone Shortcut, for example to open an app on your iPhone. ```json theme={null} { "content_state": { "title": "Deploying payments-api", "subtitle": "Running database migrations", "number_of_steps": 5, "current_step": 3, "type": "segmented_progress" }, "action": { "title": "Open Workflow", "type": "open_url", "url": "https://github.com/acme/payments-api/actions/runs/1234567890" } } ``` #### webhook Use `webhook` when the button should trigger an action in your backend, like pausing a job, acknowledging an alert, or canceling a workflow. ActivitySmith calls the URL server-side, so the user does not leave the Lock Screen. ```json theme={null} { "content_state": { "title": "Reindexing product search", "subtitle": "Shard 7 of 12", "number_of_steps": 12, "current_step": 7, "type": "segmented_progress" }, "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" } } } ``` Notes: * Only HTTPS URLs are supported for both action types. * One button per Live Activity. * Pass `action` on an update call to set or replace the button on an active Live Activity. ## Channel Targeting You can scope delivery with channel slugs: ```json theme={null} { "target": { "channels": ["devs", "ops"] } } ``` * If `target` is omitted and API key scope is `all`: send to all account recipients. * If `target` is omitted and API key scope is `channels`: send to channels assigned to that key. * If `target.channels` is present: only those channel slugs are used. # Live Activity Stream Source: https://activitysmith.com/docs/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. * 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. ## Example ```bash theme={null} curl -X PUT https://activitysmith.com/api/live-activity/stream/prod-web-1 \ -H "Authorization: Bearer $ACTIVITYSMITH_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": "%" } ] } }' ``` Call the same endpoint again with the same `stream_key` whenever the state changes. ## Timer Example Use `timer` when you need countdowns or timers. ```bash theme={null} curl -X PUT https://activitysmith.com/api/live-activity/stream/benchmark-run \ -H "Authorization: Bearer $ACTIVITYSMITH_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "content_state": { "title": "Benchmark Run", "subtitle": "sampling", "type": "timer", "duration_seconds": 300, "color": "cyan" } }' ``` For a countdown, send `duration_seconds`. You can update `title`, `subtitle`, `color`, or any other visible field as the work changes. Leave `duration_seconds` out unless you want to change the timer. To start at 00:00 and count up, set `counts_down` to `false` and leave out `duration_seconds`. ## 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. ```bash theme={null} curl -X DELETE https://activitysmith.com/api/live-activity/stream/prod-web-1 \ -H "Authorization: Bearer $ACTIVITYSMITH_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. 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 * `noop`: the incoming state matched the current state, so no update was sent * `ended`: returned by `DELETE /live-activity/stream/:stream_key` # MCP Server Source: https://activitysmith.com/docs/mcp-server Connect Claude Code, Cursor, Codex, or any MCP client to ActivitySmith so AI agents can send Push Notifications and update Live Activities on your iPhone. ## Server URL ```bash theme={null} https://mcp.activitysmith.com/mcp ``` ## What Agents Can Do Send Push Notifications to your paired devices or targeted channels. Start, update, and end Live Activities on your iPhone, like live task progress on your Lock Screen. Create widget metrics and update metric values for your Lock Screen Widgets. List the history of your Push Notifications and Live Activities. List account users and devices, manage channels, and API keys. AI agent task progress Live Activity on the iPhone Lock Screen, updated over MCP ## Setup Instructions The server URL is the same in every client. Approve the OAuth screen in your browser once, and the ActivitySmith tools become available in new sessions. ### Claude Code ```bash theme={null} claude mcp add --transport http activitysmith https://mcp.activitysmith.com/mcp ``` Then run `/mcp` inside a Claude Code session to go through the authentication flow. ### Cursor [Install in Cursor](cursor://anysphere.cursor-deeplink/mcp/install?name=activitysmith\&config=eyJ1cmwiOiJodHRwczovL21jcC5hY3Rpdml0eXNtaXRoLmNvbS9tY3AifQ==) with one click. If you prefer manual setup, add the server to `~/.cursor/mcp.json`: ```json theme={null} { "mcpServers": { "activitysmith": { "url": "https://mcp.activitysmith.com/mcp" } } } ``` Cursor prompts you to log in the first time the server is used. ### Codex ```bash theme={null} codex mcp add activitysmith --url https://mcp.activitysmith.com/mcp ``` Then authenticate: ```bash theme={null} codex mcp login activitysmith ``` ### Other MCP Clients For any client that asks for a remote MCP server URL, use: ```bash theme={null} https://mcp.activitysmith.com/mcp ``` The authorization flow happens in ActivitySmith. After approval, tools run against the account you authorized. ## OAuth ActivitySmith MCP uses OAuth. You do not need to create or paste an ActivitySmith API key into an agent prompt. During authorization, ActivitySmith shows the access requested by the client. Most clients request read and write access so the agent can inspect current state and then take action when you ask it to. ## Example Prompts ```txt theme={null} Notify me on my iPhone when this is done. ``` ```txt theme={null} Show me the progress visible on my Lock Screen with a Live Activity. ``` ```txt theme={null} Send me a Push Notification if this task gets blocked. ``` ## Tools The server exposes the following MCP tools, grouped by resource. Keep tool confirmation enabled in your client when possible, especially when you connect multiple MCP servers to the same agent session. | Resource | Tool | Description | | ------------------- | ----------------------------- | ------------------------------------------------------------------------------ | | Push Notifications | `send_push_notification` | Send a Push Notification, with optional actions, media, and channel targeting. | | Push Notifications | `list_push_notifications` | List Push Notification history for the account. | | Push Notifications | `get_push_notification` | Get one Push Notification by public ID. | | Live Activities | `set_live_activity_stream` | Start or update a managed Live Activity stream. | | Live Activities | `pause_live_activity_stream` | Pause a stream and end its current Live Activity. | | Live Activities | `resume_live_activity_stream` | Resume a paused stream so updates apply again. | | Live Activities | `end_live_activity_stream` | End the current Live Activity and remove the stream key. | | Live Activities | `list_live_activities` | List Live Activities for the account. | | Lock Screen Widgets | `create_widget_metric` | Create a widget metric definition. | | Lock Screen Widgets | `set_widget_metric_value` | Set the latest value for a widget metric. | | Lock Screen Widgets | `update_widget_metric` | Update a widget metric definition. | | Lock Screen Widgets | `list_widget_metrics` | List widget metrics for the account. | | Lock Screen Widgets | `delete_widget_metric` | Delete a widget metric. | | Channels | `create_channel` | Create a channel for targeting Push Notifications and Live Activities. | | Channels | `get_channel` | Get one channel with its assigned users and devices. | | Channels | `list_channels` | List channels for the account. | | Channels | `update_channel` | Update a channel slug. | | Channels | `set_channel_users` | Replace the user membership for a channel. | | Channels | `set_channel_devices` | Replace explicit device assignments for a channel. | | Channels | `delete_channel` | Delete a channel. | | Users and Devices | `list_account_users` | List users in the account for channel assignment. | | Users and Devices | `list_account_devices` | List active devices for explicit channel assignment. | | API Keys | `create_api_key` | Create an API key. The key secret is shown once. | | API Keys | `list_api_keys` | List API keys. Secret values are never returned. | | API Keys | `update_api_key` | Update the name or channel scope of an API key. | | API Keys | `delete_api_key` | Delete an API key by public ID. | ## Related * [Push Notifications](/docs/api-reference/endpoint/push-notification) * [Live Activity Streams](/docs/api-reference/endpoint/live-activity-stream) * [Channels](/docs/channels) * [Rate Limits](/docs/rate-limits) # Rate Limits Source: https://activitysmith.com/docs/rate-limits Rate limits for API requests ## Concurrent Live Activities Limits Concurrent Live Activities represent how many live activities ActivitySmith can process for you at the same time. Number of concurrent live activities is limited to 4. This limit mimics the number of concurrent live activities that can be processed by the iOS. If you exceed this limit, additional live activities will be ignored until resources become available. In the future, we will allow you to increase this limit by upgrading to a paid plan. If you require higher concurrency limits, please contact us at [adam@activitysmith.com](mailto:adam@activitysmith.com). ## API Rate Limits Rate limits are measured in requests per minute and are primarily in place to prevent abuse. When configured correctly, your real bottleneck will be concurrent live activities. **Shared account limit**: 60 requests per minute across these endpoints: * `POST /push-notification` * `PUT /live-activity/stream/{stream_key}` * `DELETE /live-activity/stream/{stream_key}` * `POST /metrics/{metric_key}/value` These rate limits are enforced to ensure fair usage and availability of the API for all users. If you require higher limits, please contact us at [adam@activitysmith.com](mailto:adam@activitysmith.com). # CLI Source: https://activitysmith.com/docs/sdks/cli Use the ActivitySmith CLI to send push notifications, run specific iPhone Shortcuts from notification taps or actions, update widgets, and manage Live Activities from shell scripts, CI pipelines, coding agents, and terminal workflows. ## Installation Install the ActivitySmith CLI globally with npm: ```bash CLI theme={null} # Install globally with npm npm install -g activitysmith-cli ``` ## Agent Skill Install the ActivitySmith skill when you want Codex, Claude, Cursor, or another skills-compatible agent to decide which ActivitySmith CLI command to run. ```bash CLI theme={null} npx -y skills@latest add ActivitySmithHQ/activitysmith-cli --skill activitysmith ``` Use the skill when an agent should notify you with push notifications, include a notification tap or action that can open a URL or run a specific iPhone Shortcut, or keep task progress visible with Live Activities. For example, a Codex agent can work on your computer, send a push notification when it needs your attention, and include a Shortcut action that runs an `OpenChatGPT` Shortcut on your iPhone so you can continue the conversation in the ChatGPT app. ## Usage 1. [Create an API key](https://activitysmith.com/app/keys) 2. Authenticate with `ACTIVITYSMITH_API_KEY` or pass `--api-key` per command. 3. Run `activitysmith --help` to inspect available commands. Use the environment variable when you want the cleanest shell scripts: ```bash CLI theme={null} export ACTIVITYSMITH_API_KEY="YOUR-API-KEY" activitysmith --help ``` Or pass the key directly: ```bash CLI theme={null} activitysmith --api-key "YOUR-API-KEY" push --title "Hello" ``` ## Commands ### Push Notification Use `activitysmith push` when a deploy fails, a CI run finishes, or a background job needs attention. Push notification example ```bash CLI theme={null} activitysmith push \ --title "Build Failed 🚨" \ --message "CI pipeline failed on main branch" \ --subtitle "main" ``` ### Rich Push Notifications with Media Rich push notification with image ```bash CLI theme={null} activitysmith push \ --title "Homepage ready" \ --message "Your agent finished the redesign." \ --media "https://cdn.example.com/output/homepage-v2.png" \ --redirection "https://github.com/acme/web/pull/482" ``` Send images, videos, or audio with your push notifications, press and hold to preview media directly from the notification, then tap through to open the linked content. Rich push notification with audio What will work: * direct image URL: `.jpg`, `.png`, `.gif`, etc. * direct audio file URL: `.mp3`, `.m4a`, etc. * direct video file URL: `.mp4`, `.mov`, etc. * URL that responds with a proper media `Content-Type`, even if the path has no extension `--media` can be combined with `--redirection`, but not with `--actions`. `--redirection` can be an HTTPS URL or a `shortcuts://run-shortcut?name=...` URL. ### Actionable Push Notifications Actionable push notification with redirection and actions Push notification redirection can open an HTTPS URL or run a specific iPhone Shortcut with a `shortcuts://run-shortcut?name=...` URL when someone taps the notification. For expanded notification actions, `open_url` supports HTTPS URLs and `shortcuts://run-shortcut?name=...` URLs. Webhooks are executed by the ActivitySmith backend and must use HTTPS. ```bash CLI theme={null} activitysmith push \ --title "Build Failed 🚨" \ --message "CI pipeline failed on main branch" \ --redirection "https://github.com/org/repo/actions/runs/123456789" \ --actions '[ { "title": "Open Build", "type": "open_url", "url": "https://github.com/org/repo/actions/runs/123456789" }, { "title": "Chat with Jarvis", "type": "open_url", "url": "shortcuts://run-shortcut?name=Jarvis" }, { "title": "Create Incident", "type": "webhook", "url": "https://hooks.example.com/incidents/create", "method": "POST", "body": { "service": "payments-api", "severity": "high", "source": "activitysmith-cli" } } ]' ``` You can also load actions from a file: ```bash CLI theme={null} activitysmith push \ --title "Build Failed 🚨" \ --message "CI pipeline failed on main branch" \ --actions-file "./actions.json" ``` ## Live Activities There are six types of Live Activities: * `stats`: best for showing business numbers side by side, such as revenue, sales, new users, conversion, refunds, or any other value you want visible at a glance * `metrics`: best for live percentage values that change often, like server CPU, memory usage, disk usage, or error rate * `segmented_progress`: best for anything that moves through clear stages, like deployments, onboarding flows, backups, ETL pipelines, migrations, and AI agent runs * `progress`: best for tracking real-time progress with percentage, like tasks, backups, migrations, syncs, or uploads * `alert`: best for status updates, such as feature adoption, reactivation, onboarding blockers, incidents, escalations, and other operational states * `timer`: use it when you need countdowns or timers ### Start & Update Live Activity Use a stable `stream_key` to identify the metric, job, deployment, or system you want to keep visible. The first `activity stream` command starts the Live Activity. Later commands with the same `stream_key` update it. #### Stats

Stats Live Activity stream example

```bash CLI theme={null} activitysmith activity stream sales-hourly \ --content-state '{ "title": "Sales", "subtitle": "last hour", "type": "stats", "metrics": [ { "label": "Revenue", "value": "$2430", "color": "blue" }, { "label": "Orders", "value": "37", "color": "green" }, { "label": "Conversion", "value": "4.8%", "color": "magenta" }, { "label": "Avg Order", "value": "$65.68", "color": "yellow" }, { "label": "Refunds", "value": "$84", "color": "red" }, { "label": "New Buyers", "value": "18", "color": "cyan" } ] }' ``` #### Metrics

Metrics Live Activity stream example

```bash CLI theme={null} activitysmith activity stream prod-web-1 \ --content-state '{ "title": "Server Health", "subtitle": "prod-web-1", "type": "metrics", "metrics": [ { "label": "CPU", "value": 9, "unit": "%" }, { "label": "MEM", "value": 45, "unit": "%" } ] }' ``` #### Segmented Progress

Segmented Progress Live Activity stream example

```bash CLI theme={null} activitysmith activity stream nightly-backup \ --content-state '{ "title": "Nightly Backup", "subtitle": "upload archive", "type": "segmented_progress", "numberOfSteps": 3, "currentStep": 2 }' ``` #### Progress

Progress Live Activity stream example

```bash CLI theme={null} activitysmith activity stream search-reindex \ --content-state '{ "title": "Search Reindex", "subtitle": "catalog-v2", "type": "progress", "percentage": 42 }' ``` #### Alert

Alert Live Activity stream example

```bash CLI theme={null} activitysmith activity stream customer-ops \ --content-state '{ "title": "Reactivation", "message": "Lumen came back after 2 weeks", "type": "alert", "icon": { "symbol": "cloud.sun", "color": "yellow" }, "badge": { "title": "Customer", "color": "magenta" } }' ``` #### Timer

Timer Live Activity stream example

```bash CLI theme={null} activitysmith activity stream benchmark-run \ --content-state '{ "title": "Benchmark Run", "subtitle": "sampling", "type": "timer", "duration_seconds": 300, "color": "cyan" }' ``` For a countdown, send `duration_seconds`. You can update `title`, `subtitle`, `color`, or any other visible field as the work changes. Leave `duration_seconds` out unless you want to change the timer. To start at 00:00 and count up, set `counts_down` to `false` and leave out `duration_seconds`. ### End Live Activity Call `activity end-stream` with the same `stream_key` 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 `autoDismissMinutes` to choose a different dismissal time, including `0` for immediate dismissal. ```bash CLI theme={null} activitysmith activity end-stream prod-web-1 \ --content-state '{ "title": "Server Health", "subtitle": "prod-web-1", "type": "metrics", "metrics": [ { "label": "CPU", "value": 7, "unit": "%" }, { "label": "MEM", "value": 38, "unit": "%" } ], "autoDismissMinutes": 2 }' ``` ### Icons and Badges Add more context to Live Activities with icons and badges. #### Icon Supported Live Activity types: `stats`, `metrics`, `progress`, `segmented_progress`, `alert`, and `timer`.

Metrics Live Activity with an SF Symbol icon on the iPhone Lock Screen

```bash theme={null} activitysmith activity stream prod-web-1 \ --content-state '{ "title": "Server Health", "subtitle": "prod-web-1", "type": "metrics", "icon": { "symbol": "server.rack", "color": "blue" }, "metrics": [ { "label": "CPU", "value": 18, "unit": "%" }, { "label": "MEM", "value": 42, "unit": "%" } ] }' ``` The `icon.symbol` value is an Apple SF Symbol name. Browse the catalog with one of these tools: * [ActivitySmith app](https://apps.apple.com/us/app/activitysmith/id6752254835) - Open Settings -> SF Symbols to browse 45 hand-picked icons ready to use * [SF Symbols](https://developer.apple.com/sf-symbols/) - Apple's official macOS app * [Interactful](https://apps.apple.com/app/interactful/id1528095640) - free third-party iOS app listing all SF Symbols under Foundations -> Iconography #### Badge Badges are supported by `alert`, `progress`, and `segmented_progress` Live Activities.

Progress Live Activity with a badge on the iPhone Lock Screen

```bash theme={null} activitysmith activity stream nightly-database-backup \ --content-state '{ "title": "Nightly Database Backup", "subtitle": "verify restore", "type": "progress", "badge": { "title": "S3", "color": "cyan" }, "percentage": 62 }' ``` ### Live Activity Colors Choose from these colors for the Live Activity accent, including progress bars and action buttons, or apply them to an individual icon or badge: `lime`, `green`, `cyan`, `blue`, `purple`, `magenta`, `red`, `orange`, `yellow`, `gray` ### Live Activity Action

Metrics Live Activity with action

Live Activities can include an action button. * `open_url`: open an HTTPS URL. * `open_url` with a `shortcuts://run-shortcut?name=...` URL: run a specific iPhone Shortcut, for example to open an app. * `webhook`: trigger a backend GET/POST workflow. #### Open URL action ```bash CLI theme={null} activitysmith activity stream prod-web-1 \ --content-state '{ "title": "Server Health", "subtitle": "prod-web-1", "type": "metrics", "metrics": [ { "label": "CPU", "value": 76, "unit": "%" }, { "label": "MEM", "value": 52, "unit": "%" } ] }' \ --action '{ "title": "Dashboard", "type": "open_url", "url": "https://status.example.com/servers/prod-web-1" }' ``` #### Apple Shortcut action ```bash CLI theme={null} activitysmith activity stream prod-web-1 \ --content-state '{ "title": "Server Health", "subtitle": "prod-web-1", "type": "metrics", "metrics": [ { "label": "CPU", "value": 76, "unit": "%" }, { "label": "MEM", "value": 52, "unit": "%" } ] }' \ --action '{ "title": "Chat with Jarvis", "type": "open_url", "url": "shortcuts://run-shortcut?name=Jarvis" }' ``` #### Webhook action ```bash CLI theme={null} activitysmith activity stream search-reindex \ --content-state '{ "title": "Reindexing product search", "subtitle": "Shard 7 of 12", "type": "segmented_progress", "numberOfSteps": 12, "currentStep": 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-cli" } }' ``` #### Secondary action ![Alert Live Activity with primary and secondary action buttons](https://cdn.activitysmith.com/features/live-activity-secondary-action.png) Use `--secondary-action` when you want a second button beside the primary `--action`. The secondary action button is supported for `alert`, `progress`, and `segmented_progress` Live Activities. Both buttons use the same `open_url`, `webhook`, and Apple Shortcut payload shapes. ```bash CLI theme={null} activitysmith activity stream agent-approval \ --content-state '{ "title": "Approval Needed", "message": "Should I send the follow-up email to Brightlane?", "type": "alert", "color": "green", "icon": { "symbol": "sparkles", "color": "green" }, "badge": { "title": "Agent", "color": "green" } }' \ --action '{ "title": "Send", "type": "webhook", "url": "https://agent.example.com/live-activity/approve", "method": "POST", "body": { "approval_id": "approval_01JY3J7Q9S0P8M1V5PZK7DR4M2", "decision": "send" } }' \ --secondary-action '{ "title": "Deny", "type": "webhook", "url": "https://agent.example.com/live-activity/deny", "method": "POST", "body": { "approval_id": "approval_01JY3J7Q9S0P8M1V5PZK7DR4M2", "decision": "deny" } }' ``` ## Channels Use `--channels` to target specific channels for `push` and `activity stream`. ```bash CLI theme={null} activitysmith push \ --title "Build Failed 🚨" \ --message "CI pipeline failed on main branch" \ --channels "devs,ops" ``` ```bash CLI theme={null} activitysmith activity stream nightly-backup \ --content-state '{ "title": "Nightly database backup", "type": "segmented_progress", "numberOfSteps": 4, "currentStep": 1 }' \ --channels "devs,ops" ``` ## Widgets

Lock screen widgets

ActivitySmith lets you display any value on your Lock Screen with widgets - SaaS metrics, revenue, signups, uptime, habits, or anything else you want to track. Create a metric in the web app, then update the metric value using our API, add a widget to your lock screen and it will fetch the latest update automatically.

Create widget metric

Use the metric key to update its value. ```bash theme={null} activitysmith metrics update deploy.success_rate 99.9 ``` String metric values work too. ```bash theme={null} activitysmith metrics update prod.status healthy ``` ## Output Use `--json` for machine-readable output: ```bash CLI theme={null} activitysmith push --title "Hello" --json ``` ## Error Handling The CLI exits non-zero on non-2xx responses and prints the API error body. That includes validation failures, rate limits, and Live Activity limit errors. ## Additional Resources Install the ActivitySmith CLI from npm View the CLI source on GitHub # Go Source: https://activitysmith.com/docs/sdks/go Use the ActivitySmith Go SDK to send push notifications and Live Activity progress updates from Go services, workers, and automation jobs. ## Installation Install the ActivitySmith Go SDK with `go get`: ```go Go theme={null} go get github.com/ActivitySmithHQ/activitysmith-go ``` ## Usage 1. [Create an API key](https://activitysmith.com/app/keys) 2. Pass the API key into `activitysmithsdk.New`. 3. Reuse the client anywhere you send pushes or Live Activity updates. Create the client once: ```go Go theme={null} package main import ( "log" activitysmithsdk "github.com/ActivitySmithHQ/activitysmith-go" ) func main() { activitysmith, err := activitysmithsdk.New("YOUR-API-KEY") if err != nil { log.Fatal(err) } } ``` ### Send a Push Notification Use `activitysmith.Notifications.Send` when a deploy finishes, a customer upgrades, or a background job needs attention. Push notification example for a new subscription event ```go Go theme={null} input := activitysmithsdk.PushNotificationInput{ Title: "New subscription 💸", Message: "Customer upgraded to Pro plan", } _, err := activitysmith.Notifications. Send(input) if err != nil { log.Fatal(err) } ``` ### Rich Push Notifications with Media Rich push notification with image ```go Go theme={null} input := activitysmithsdk.PushNotificationInput{ Title: "Homepage ready", Message: "Your agent finished the redesign.", Media: "https://cdn.example.com/output/homepage-v2.png", Redirection: "https://github.com/acme/web/pull/482", } _, err := activitysmith.Notifications. Send(input) if err != nil { log.Fatal(err) } ``` Send images, videos, or audio with your push notifications, press and hold to preview media directly from the notification, then tap through to open the linked content. Rich push notification with audio What will work: * direct image URL: `.jpg`, `.png`, `.gif`, etc. * direct audio file URL: `.mp3`, `.m4a`, etc. * direct video file URL: `.mp4`, `.mov`, etc. * URL that responds with a proper media `Content-Type`, even if the path has no extension `Media` can be combined with `Redirection`, but not with `Actions`. `Redirection` can be an HTTPS URL or a `shortcuts://run-shortcut?name=...` URL. ### Actionable Push Notifications Actionable push notification with redirection and actions Push notification redirection can open an HTTPS URL or run a specific iPhone Shortcut with a `shortcuts://run-shortcut?name=...` URL when someone taps the notification. For expanded notification actions, `open_url` supports HTTPS URLs and `shortcuts://run-shortcut?name=...` URLs. Webhooks are executed by the ActivitySmith backend and must use HTTPS. ```go Go theme={null} import ( "log" activitysmithsdk "github.com/ActivitySmithHQ/activitysmith-go" ) input := activitysmithsdk.PushNotificationInput{ Title: "New subscription 💸", Message: "Customer upgraded to Pro plan", Redirection: "https://crm.example.com/customers/cus_9f3a1d", Actions: []activitysmithsdk.PushNotificationAction{ activitysmithsdk.PushAction( "Open CRM", "open_url", "https://crm.example.com/customers/cus_9f3a1d", ), activitysmithsdk.PushAction( "Chat with Jarvis", "open_url", "shortcuts://run-shortcut?name=Jarvis", ), activitysmithsdk.PushAction( "Start Onboarding Workflow", "webhook", "https://hooks.example.com/activitysmith/onboarding/start", activitysmithsdk.PushActionMethod("POST"), activitysmithsdk.PushActionBody(map[string]interface{}{ "customer_id": "cus_9f3a1d", "plan": "pro", }), ), }, } _, err := activitysmith.Notifications. Send(input) if err != nil { log.Fatal(err) } ``` ## Live Activities There are six types of Live Activities: * `stats`: best for showing business numbers side by side, such as revenue, sales, new users, conversion, refunds, or any other value you want visible at a glance * `metrics`: best for live percentage values that change often, like server CPU, memory usage, disk usage, or error rate * `segmented_progress`: best for anything that moves through clear stages, like deployments, onboarding flows, backups, ETL pipelines, migrations, and AI agent runs * `progress`: best for tracking real-time progress with percentage, like tasks, backups, migrations, syncs, or uploads * `alert`: best for status updates, such as feature adoption, reactivation, onboarding blockers, incidents, escalations, and other operational states * `timer`: use it when you need countdowns or timers ### Start & Update Live Activity Use a stable `streamKey` to identify the metric, job, deployment, or system you want to keep visible. The first `Stream(...)` call starts the Live Activity. Later calls with the same `streamKey` update it. #### Stats

Stats Live Activity stream example

```go theme={null} activitysmith.LiveActivities.Stream( "sales-hourly", activitysmithsdk.LiveActivityStreamInput{ Title: "Sales", Subtitle: "last hour", Type: "stats", Metrics: []activitysmithsdk.ActivityMetric{ activitysmithsdk.Metric("Revenue", "$2430", activitysmithsdk.MetricColor("blue")), activitysmithsdk.Metric("Orders", "37", activitysmithsdk.MetricColor("green")), activitysmithsdk.Metric("Conversion", "4.8%", activitysmithsdk.MetricColor("magenta")), activitysmithsdk.Metric("Avg Order", "$65.68", activitysmithsdk.MetricColor("yellow")), activitysmithsdk.Metric("Refunds", "$84", activitysmithsdk.MetricColor("red")), activitysmithsdk.Metric("New Buyers", "18", activitysmithsdk.MetricColor("cyan")), }, }, ) ``` #### Metrics

Metrics Live Activity stream example

```go theme={null} activitysmith.LiveActivities.Stream( "prod-web-1", activitysmithsdk.LiveActivityStreamInput{ Title: "Server Health", Subtitle: "prod-web-1", Type: "metrics", Metrics: []activitysmithsdk.ActivityMetric{ activitysmithsdk.Metric("CPU", 9, activitysmithsdk.MetricUnit("%")), activitysmithsdk.Metric("MEM", 45, activitysmithsdk.MetricUnit("%")), }, }, ) ``` #### Segmented Progress

Segmented Progress Live Activity stream example

```go theme={null} activitysmith.LiveActivities.Stream( "nightly-backup", activitysmithsdk.LiveActivityStreamInput{ Title: "Nightly Backup", Subtitle: "upload archive", Type: "segmented_progress", NumberOfSteps: 3, CurrentStep: 2, }, ) ``` #### Progress

Progress Live Activity stream example

```go theme={null} activitysmith.LiveActivities.Stream( "search-reindex", activitysmithsdk.LiveActivityStreamInput{ Title: "Search Reindex", Subtitle: "catalog-v2", Type: "progress", Percentage: 42, }, ) ``` #### Alert

Alert Live Activity stream example

```go theme={null} activitysmith.LiveActivities.Stream( "customer-ops", activitysmithsdk.LiveActivityStreamInput{ Title: "Reactivation", Message: "Lumen came back after 2 weeks", Type: activitysmithsdk.LiveActivityTypeAlert, Icon: activitysmithsdk.AlertIcon("cloud.sun", "yellow"), Badge: activitysmithsdk.AlertBadge("Customer", "magenta"), }, ) ``` #### Timer

Timer Live Activity stream example

```go theme={null} activitysmith.LiveActivities.Stream( "benchmark-run", activitysmithsdk.LiveActivityStreamInput{ Title: "Benchmark Run", Subtitle: "sampling", Type: "timer", DurationSeconds: 300, Color: "cyan", }, ) ``` For a countdown, send `DurationSeconds`. You can update `Title`, `Subtitle`, `Color`, or any other visible field as the work changes. Leave `DurationSeconds` out unless you want to change the timer. To start at 00:00 and count up, set `CountsDown` to `false` and leave out `DurationSeconds`. ### End Live Activity Call `EndStream(...)` with the same `streamKey` 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 `AutoDismissMinutes` to choose a different dismissal time, including `0` for immediate dismissal. ```go theme={null} activitysmith.LiveActivities.EndStream( "prod-web-1", activitysmithsdk.LiveActivityStreamEndInput{ Title: "Server Health", Subtitle: "prod-web-1", Type: "metrics", Metrics: []activitysmithsdk.ActivityMetric{ activitysmithsdk.Metric("CPU", 7, activitysmithsdk.MetricUnit("%")), activitysmithsdk.Metric("MEM", 38, activitysmithsdk.MetricUnit("%")), }, AutoDismissMinutes: 2, }, ) ``` ### Icons and Badges Add more context to Live Activities with icons and badges. #### Icon Supported Live Activity types: `stats`, `metrics`, `progress`, `segmented_progress`, `alert`, and `timer`.

Metrics Live Activity with an SF Symbol icon on the iPhone Lock Screen

```go theme={null} activitysmith.LiveActivities.Stream( "prod-web-1", activitysmithsdk.LiveActivityStreamInput{ Title: "Server Health", Subtitle: "prod-web-1", Type: "metrics", Icon: activitysmithsdk.AlertIcon("server.rack", "blue"), Metrics: []activitysmithsdk.ActivityMetric{ activitysmithsdk.Metric("CPU", 18, activitysmithsdk.MetricUnit("%")), activitysmithsdk.Metric("MEM", 42, activitysmithsdk.MetricUnit("%")), }, }, ) ``` The `Icon` symbol value is an Apple SF Symbol name. Browse the catalog with one of these tools: * [ActivitySmith app](https://apps.apple.com/us/app/activitysmith/id6752254835) - Open Settings -> SF Symbols to browse 45 hand-picked icons ready to use * [SF Symbols](https://developer.apple.com/sf-symbols/) - Apple's official macOS app * [Interactful](https://apps.apple.com/app/interactful/id1528095640) - free third-party iOS app listing all SF Symbols under Foundations -> Iconography #### Badge Badges are supported by `alert`, `progress`, and `segmented_progress` Live Activities.

Progress Live Activity with a badge on the iPhone Lock Screen

```go theme={null} activitysmith.LiveActivities.Stream( "nightly-database-backup", activitysmithsdk.LiveActivityStreamInput{ Title: "Nightly Database Backup", Subtitle: "verify restore", Type: "progress", Badge: activitysmithsdk.AlertBadge("S3", "cyan"), Percentage: 62, }, ) ``` ### Live Activity Colors Choose from these colors for the Live Activity accent, including progress bars and action buttons, or apply them to an individual icon or badge: `lime`, `green`, `cyan`, `blue`, `purple`, `magenta`, `red`, `orange`, `yellow`, `gray` ### Live Activity Action

Metrics Live Activity with action

Live Activities can include an action button. * `open_url`: open an HTTPS URL. * `open_url` with a `shortcuts://run-shortcut?name=...` URL: run a specific iPhone Shortcut, for example to open an app. * `webhook`: trigger a backend GET/POST workflow. #### Open URL action ```go theme={null} activitysmith.LiveActivities.Stream( "prod-web-1", activitysmithsdk.LiveActivityStreamInput{ Title: "Server Health", Subtitle: "prod-web-1", Type: "metrics", Metrics: []activitysmithsdk.ActivityMetric{ activitysmithsdk.Metric("CPU", 76, activitysmithsdk.MetricUnit("%")), activitysmithsdk.Metric("MEM", 52, activitysmithsdk.MetricUnit("%")), }, Action: &activitysmithsdk.LiveActivityActionInput{ Title: "Dashboard", Type: "open_url", URL: "https://status.example.com/servers/prod-web-1", }, }, ) ``` #### Apple Shortcut action ```go theme={null} activitysmith.LiveActivities.Stream( "prod-web-1", activitysmithsdk.LiveActivityStreamInput{ Title: "Server Health", Subtitle: "prod-web-1", Type: "metrics", Metrics: []activitysmithsdk.ActivityMetric{ activitysmithsdk.Metric("CPU", 76, activitysmithsdk.MetricUnit("%")), activitysmithsdk.Metric("MEM", 52, activitysmithsdk.MetricUnit("%")), }, Action: &activitysmithsdk.LiveActivityActionInput{ Title: "Chat with Jarvis", Type: "open_url", URL: "shortcuts://run-shortcut?name=Jarvis", }, }, ) ``` #### Webhook action ```go theme={null} activitysmith.LiveActivities.Stream( "search-reindex", activitysmithsdk.LiveActivityStreamInput{ Title: "Reindexing product search", Subtitle: "Shard 7 of 12", Type: "segmented_progress", NumberOfSteps: 12, CurrentStep: 7, Action: &activitysmithsdk.LiveActivityActionInput{ Title: "Pause Reindex", Type: "webhook", URL: "https://ops.example.com/hooks/search/reindex/pause", Method: "POST", Body: map[string]interface{}{ "job_id": "reindex-2026-03-19", "requested_by": "activitysmith-go", }, }, }, ) ``` #### Secondary action ![Alert Live Activity with primary and secondary action buttons](https://cdn.activitysmith.com/features/live-activity-secondary-action.png) Use `secondary_action` when you want a second button beside the primary `action`. The secondary action button is supported for `alert`, `progress`, and `segmented_progress` Live Activities. Both buttons use the same `open_url`, `webhook`, and Apple Shortcut payload shapes. ```go theme={null} activitysmith.LiveActivities.Stream( "agent-approval", activitysmithsdk.LiveActivityStreamInput{ Title: "Approval Needed", Message: "Should I send the follow-up email to Brightlane?", Type: "alert", Color: "green", Icon: activitysmithsdk.AlertIcon("sparkles", "green"), Badge: activitysmithsdk.AlertBadge("Agent", "green"), Action: &activitysmithsdk.LiveActivityActionInput{ Title: "Send", Type: "webhook", URL: "https://agent.example.com/live-activity/approve", Method: "POST", Body: map[string]interface{}{ "approval_id": "approval_01JY3J7Q9S0P8M1V5PZK7DR4M2", "decision": "send", }, }, SecondaryAction: &activitysmithsdk.LiveActivityActionInput{ Title: "Deny", Type: "webhook", URL: "https://agent.example.com/live-activity/deny", Method: "POST", Body: map[string]interface{}{ "approval_id": "approval_01JY3J7Q9S0P8M1V5PZK7DR4M2", "decision": "deny", }, }, }, ) ``` ## Channels Target specific channels when sending a push notification or streaming a Live Activity. ```go Go theme={null} activitysmith.Notifications.Send(activitysmithsdk.PushNotificationInput{ Title: "New subscription 💸", Message: "Customer upgraded to Pro plan", Channels: []string{"ios-builds", "engineering"}, }) activitysmith.LiveActivities.Stream( "nightly-backup", activitysmithsdk.LiveActivityStreamInput{ Title: "Nightly database backup", NumberOfSteps: 3, CurrentStep: 1, Type: "segmented_progress", Channels: []string{"ios-builds"}, }, ) ``` ## Widgets

Lock screen widgets

ActivitySmith lets you display any value on your Lock Screen with widgets - SaaS metrics, revenue, signups, uptime, habits, or anything else you want to track. Create a metric in the web app, then update the metric value using our API, add a widget to your lock screen and it will fetch the latest update automatically.

Create widget metric

Use the metric key to update its value. ```go theme={null} _, err := activitysmith.Metrics.Update("deploy.success_rate", 99.9) if err != nil { log.Fatal(err) } ``` String metric values work too. ```go theme={null} _, err = activitysmith.Metrics.Update("prod.status", "healthy") if err != nil { log.Fatal(err) } ``` ## Error Handling SDK calls return `response, err`, so check `err` after every call. ## Additional Resources View the Go SDK source on GitHub # Node.js Source: https://activitysmith.com/docs/sdks/node Use the ActivitySmith Node.js SDK to send push notifications and Live Activity progress updates from Node services, jobs, and CI workflows. ## Installation Install the ActivitySmith Node.js SDK with npm: ```js Node theme={null} npm install activitysmith ``` ## Usage 1. [Create an API key](https://activitysmith.com/app/keys) 2. Set `ACTIVITYSMITH_API_KEY` or pass `apiKey` when creating the client. 3. Reuse the client anywhere you send pushes or Live Activity updates. Create the client once: ```js Node theme={null} import ActivitySmith from "activitysmith"; const activitysmith = new ActivitySmith({ apiKey: process.env.ACTIVITYSMITH_API_KEY, }); ``` ### Send a Push Notification Use `activitysmith.notifications.send` when a deploy finishes, a customer upgrades, or a background job needs attention. `title` is required. `message` and `subtitle` are optional. Push notification example for a new subscription event ```js Node theme={null} await activitysmith.notifications.send({ title: "New subscription 💸", message: "Customer upgraded to Pro plan", }); ``` ### Rich Push Notifications with Media Rich push notification with image ```js Node theme={null} await activitysmith.notifications.send({ title: "Homepage ready", message: "Your agent finished the redesign.", media: "https://cdn.example.com/output/homepage-v2.png", redirection: "https://github.com/acme/web/pull/482", }); ``` Send images, videos, or audio with your push notifications, press and hold to preview media directly from the notification, then tap through to open the linked content. Rich push notification with audio What will work: * direct image URL: `.jpg`, `.png`, `.gif`, etc. * direct audio file URL: `.mp3`, `.m4a`, etc. * direct video file URL: `.mp4`, `.mov`, etc. * URL that responds with a proper media `Content-Type`, even if the path has no extension `media` can be combined with `redirection`, but not with `actions`. `redirection` can be an HTTPS URL or a `shortcuts://run-shortcut?name=...` URL. ### Actionable Push Notifications Actionable push notification with redirection and actions Push notification redirection can open an HTTPS URL or run a specific iPhone Shortcut with a `shortcuts://run-shortcut?name=...` URL when someone taps the notification. For expanded notification actions, `open_url` supports HTTPS URLs and `shortcuts://run-shortcut?name=...` URLs. Webhooks are executed by the ActivitySmith backend and must use HTTPS. ```js Node theme={null} await activitysmith.notifications.send({ title: "New subscription 💸", message: "Customer upgraded to Pro plan", redirection: "https://crm.example.com/customers/cus_9f3a1d", actions: [ { title: "Open CRM", type: "open_url", url: "https://crm.example.com/customers/cus_9f3a1d", }, { title: "Chat with Jarvis", type: "open_url", url: "shortcuts://run-shortcut?name=Jarvis", }, { title: "Start Onboarding Workflow", type: "webhook", url: "https://hooks.example.com/activitysmith/onboarding/start", method: "POST", body: { customer_id: "cus_9f3a1d", plan: "pro", }, }, ], }); ``` ## Live Activities There are six types of Live Activities: * `stats`: best for showing business numbers side by side, such as revenue, sales, new users, conversion, refunds, or any other value you want visible at a glance * `metrics`: best for live percentage values that change often, like server CPU, memory usage, disk usage, or error rate * `segmented_progress`: best for anything that moves through clear stages, like deployments, onboarding flows, backups, ETL pipelines, migrations, and AI agent runs * `progress`: best for tracking real-time progress with percentage, like tasks, backups, migrations, syncs, or uploads * `alert`: best for status updates, such as feature adoption, reactivation, onboarding blockers, incidents, escalations, and other operational states * `timer`: use it when you need countdowns or timers ### Start & Update Live Activity Use a stable `streamKey` to identify the metric, job, deployment, or system you want to keep visible. The first `stream(...)` call starts the Live Activity. Later calls with the same `streamKey` update it. #### Stats

Stats Live Activity stream example

```ts theme={null} await activitysmith.liveActivities.stream("sales-hourly", { content_state: { title: "Sales", subtitle: "last hour", type: "stats", metrics: [ { label: "Revenue", value: "$2430", color: "blue" }, { label: "Orders", value: "37", color: "green" }, { label: "Conversion", value: "4.8%", color: "magenta" }, { label: "Avg Order", value: "$65.68", color: "yellow" }, { label: "Refunds", value: "$84", color: "red" }, { label: "New Buyers", value: "18", color: "cyan" }, ], }, }); ``` #### Metrics

Metrics Live Activity stream example

```ts theme={null} await activitysmith.liveActivities.stream("prod-web-1", { content_state: { title: "Server Health", subtitle: "prod-web-1", type: "metrics", metrics: [ { label: "CPU", value: 9, unit: "%" }, { label: "MEM", value: 45, unit: "%" }, ], }, }); ``` #### Segmented Progress

Segmented Progress Live Activity stream example

```ts theme={null} await activitysmith.liveActivities.stream("nightly-backup", { content_state: { title: "Nightly Backup", subtitle: "upload archive", type: "segmented_progress", number_of_steps: 3, current_step: 2, }, }); ``` #### Progress

Progress Live Activity stream example

```ts theme={null} await activitysmith.liveActivities.stream("search-reindex", { content_state: { title: "Search Reindex", subtitle: "catalog-v2", type: "progress", percentage: 42, }, }); ``` #### Alert

Alert Live Activity stream example

```ts theme={null} await activitysmith.liveActivities.stream("customer-ops", { content_state: ActivitySmith.contentState({ title: "Reactivation", message: "Lumen came back after 2 weeks", type: "alert", icon: ActivitySmith.alertIcon("cloud.sun", { color: "yellow" }), badge: ActivitySmith.alertBadge("Customer", { color: "magenta" }), }), }); ``` #### Timer

Timer Live Activity stream example

```ts theme={null} await activitysmith.liveActivities.stream("benchmark-run", { content_state: { title: "Benchmark Run", subtitle: "sampling", type: "timer", duration_seconds: 300, color: "cyan", }, }); ``` For a countdown, send `duration_seconds`. You can update `title`, `subtitle`, `color`, or any other visible field as the work changes. Leave `duration_seconds` out unless you want to change the timer. To start at 00:00 and count up, set `counts_down: false` and leave out `duration_seconds`. ### End Live Activity Call `endStream(...)` with the same `streamKey` 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. ```ts theme={null} await activitysmith.liveActivities.endStream("prod-web-1", { 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, }, }); ``` ### Icons and Badges Add more context to Live Activities with icons and badges. #### Icon Supported Live Activity types: `stats`, `metrics`, `progress`, `segmented_progress`, `alert`, and `timer`.

Metrics Live Activity with an SF Symbol icon on the iPhone Lock Screen

```ts theme={null} await activitysmith.liveActivities.stream("prod-web-1", { content_state: ActivitySmith.contentState({ title: "Server Health", subtitle: "prod-web-1", type: "metrics", icon: ActivitySmith.alertIcon("server.rack", { color: "blue" }), metrics: [ { label: "CPU", value: 18, unit: "%" }, { label: "MEM", value: 42, unit: "%" }, ], }), }); ``` The `icon.symbol` value is an Apple SF Symbol name. Browse the catalog with one of these tools: * [ActivitySmith app](https://apps.apple.com/us/app/activitysmith/id6752254835) - Open Settings -> SF Symbols to browse 45 hand-picked icons ready to use * [SF Symbols](https://developer.apple.com/sf-symbols/) - Apple's official macOS app * [Interactful](https://apps.apple.com/app/interactful/id1528095640) - free third-party iOS app listing all SF Symbols under Foundations -> Iconography #### Badge Badges are supported by `alert`, `progress`, and `segmented_progress` Live Activities.

Progress Live Activity with a badge on the iPhone Lock Screen

```ts theme={null} await activitysmith.liveActivities.stream("nightly-database-backup", { content_state: ActivitySmith.contentState({ title: "Nightly Database Backup", subtitle: "verify restore", type: "progress", badge: ActivitySmith.alertBadge("S3", { color: "cyan" }), percentage: 62, }), }); ``` ### Live Activity Colors Choose from these colors for the Live Activity accent, including progress bars and action buttons, or apply them to an individual icon or badge: `lime`, `green`, `cyan`, `blue`, `purple`, `magenta`, `red`, `orange`, `yellow`, `gray` ### Live Activity Action

Metrics Live Activity with action

Live Activities can include an action button. * `open_url`: open an HTTPS URL. * `open_url` with a `shortcuts://run-shortcut?name=...` URL: run a specific iPhone Shortcut, for example to open an app. * `webhook`: trigger a backend GET/POST workflow. #### Open URL action ```ts theme={null} await activitysmith.liveActivities.stream("prod-web-1", { content_state: { title: "Server Health", subtitle: "prod-web-1", type: "metrics", metrics: [ { label: "CPU", value: 76, unit: "%" }, { label: "MEM", value: 52, unit: "%" }, ], }, action: { title: "Dashboard", type: "open_url", url: "https://status.example.com/servers/prod-web-1", }, }); ``` #### Apple Shortcut action ```ts theme={null} await activitysmith.liveActivities.stream("prod-web-1", { content_state: { title: "Server Health", subtitle: "prod-web-1", type: "metrics", metrics: [ { label: "CPU", value: 76, unit: "%" }, { label: "MEM", value: 52, unit: "%" }, ], }, action: { title: "Chat with Jarvis", type: "open_url", url: "shortcuts://run-shortcut?name=Jarvis", }, }); ``` #### Webhook action ```ts theme={null} await activitysmith.liveActivities.stream("search-reindex", { content_state: { title: "Reindexing product search", subtitle: "Shard 7 of 12", type: "segmented_progress", 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-node", }, }, }); ``` #### Secondary action ![Alert Live Activity with primary and secondary action buttons](https://cdn.activitysmith.com/features/live-activity-secondary-action.png) Use `secondary_action` when you want a second button beside the primary `action`. The secondary action button is supported for `alert`, `progress`, and `segmented_progress` Live Activities. Both buttons use the same `open_url`, `webhook`, and Apple Shortcut payload shapes. ```ts theme={null} await activitysmith.liveActivities.stream("agent-approval", { content_state: { title: "Approval Needed", message: "Should I send the follow-up email to Brightlane?", type: "alert", color: "green", icon: { symbol: "sparkles", color: "green", }, badge: { title: "Agent", color: "green", }, }, action: { title: "Send", type: "webhook", url: "https://agent.example.com/live-activity/approve", method: "POST", body: { approval_id: "approval_01JY3J7Q9S0P8M1V5PZK7DR4M2", decision: "send", }, }, secondary_action: { title: "Deny", type: "webhook", url: "https://agent.example.com/live-activity/deny", method: "POST", body: { approval_id: "approval_01JY3J7Q9S0P8M1V5PZK7DR4M2", decision: "deny", }, }, }); ``` ## Channels Target specific channels when sending a push notification or streaming a Live Activity. ```js Node theme={null} await activitysmith.notifications.send({ title: "New subscription 💸", message: "Customer upgraded to Pro plan", channels: ["ios-builds", "engineering"], }); await activitysmith.liveActivities.stream("nightly-backup", { channels: ["ios-builds"], content_state: { title: "Nightly database backup", number_of_steps: 3, current_step: 1, type: "segmented_progress", }, }); ``` ## Widgets

Lock screen widgets

ActivitySmith lets you display any value on your Lock Screen with widgets - SaaS metrics, revenue, signups, uptime, habits, or anything else you want to track. Create a metric in the web app, then update the metric value using our API, add a widget to your lock screen and it will fetch the latest update automatically.

Create widget metric

Use the metric key to update its value. ```ts theme={null} await activitysmith.metrics.update("deploy.success_rate", 99.9); ``` String metric values work too. ```ts theme={null} await activitysmith.metrics.update("prod.status", "healthy"); ``` ## Error Handling SDK calls return promises, so wrap API calls with `try/catch`: ```js Node theme={null} try { await activitysmith.notifications.send({ title: "Hello" }); } catch (error) { console.error(error); } ``` ## Additional Resources Install the ActivitySmith Node.js SDK from npm View the Node.js SDK source on GitHub # Overview Source: https://activitysmith.com/docs/sdks/overview ActivitySmith SDKs and the CLI help you send push notifications, update widgets, and manage Live Activities on your iOS devices. ## Official SDKs Explore the Node SDK for ActivitySmith. Explore the Python SDK for ActivitySmith. Explore the Go SDK for ActivitySmith. Explore the PHP SDK for ActivitySmith. Explore the Ruby SDK for ActivitySmith. Use ActivitySmith directly from the command line. # PHP Source: https://activitysmith.com/docs/sdks/php Use the ActivitySmith PHP SDK to send push notifications and Live Activity progress updates from PHP apps, queues, and scheduled jobs. ## Installation Install the ActivitySmith PHP SDK with Composer: ```php PHP theme={null} composer require activitysmith/activitysmith ``` ## Usage 1. [Create an API key](https://activitysmith.com/app/keys) 2. Set `ACTIVITYSMITH_API_KEY` or pass it directly to `ActivitySmith`. 3. Reuse the client anywhere you send pushes or Live Activity updates. Create the client once: ```php PHP theme={null} notifications->send` when a deploy finishes, a customer upgrades, or a background job needs attention. `title` is required. `message` and `subtitle` are optional. Push notification example for a new subscription event ```php PHP theme={null} $activitysmith->notifications->send( title: 'New subscription 💸', message: 'Customer upgraded to Pro plan', ); ``` ### Rich Push Notifications with Media Rich push notification with image ```php PHP theme={null} $activitysmith->notifications->send( title: 'Homepage ready', message: 'Your agent finished the redesign.', media: 'https://cdn.example.com/output/homepage-v2.png', redirection: 'https://github.com/acme/web/pull/482', ); ``` Send images, videos, or audio with your push notifications, press and hold to preview media directly from the notification, then tap through to open the linked content. Rich push notification with audio What will work: * direct image URL: `.jpg`, `.png`, `.gif`, etc. * direct audio file URL: `.mp3`, `.m4a`, etc. * direct video file URL: `.mp4`, `.mov`, etc. * URL that responds with a proper media `Content-Type`, even if the path has no extension `media` can be combined with `redirection`, but not with `actions`. `redirection` can be an HTTPS URL or a `shortcuts://run-shortcut?name=...` URL. ### Actionable Push Notifications Actionable push notification with redirection and actions Push notification redirection can open an HTTPS URL or run a specific iPhone Shortcut with a `shortcuts://run-shortcut?name=...` URL when someone taps the notification. For expanded notification actions, `open_url` supports HTTPS URLs and `shortcuts://run-shortcut?name=...` URLs. Webhooks are executed by the ActivitySmith backend and must use HTTPS. ```php PHP theme={null} $activitysmith->notifications->send( title: 'New subscription 💸', message: 'Customer upgraded to Pro plan', redirection: 'https://crm.example.com/customers/cus_9f3a1d', actions: [ PushAction::make( title: 'Open CRM', type: 'open_url', url: 'https://crm.example.com/customers/cus_9f3a1d', ), PushAction::make( title: 'Chat with Jarvis', type: 'open_url', url: 'shortcuts://run-shortcut?name=Jarvis', ), PushAction::make( title: 'Start Onboarding Workflow', type: 'webhook', url: 'https://hooks.example.com/activitysmith/onboarding/start', method: 'POST', body: [ 'customer_id' => 'cus_9f3a1d', 'plan' => 'pro', ], ), ], ); ``` ## Live Activities There are six types of Live Activities: * `stats`: best for showing business numbers side by side, such as revenue, sales, new users, conversion, refunds, or any other value you want visible at a glance * `metrics`: best for live percentage values that change often, like server CPU, memory usage, disk usage, or error rate * `segmented_progress`: best for anything that moves through clear stages, like deployments, onboarding flows, backups, ETL pipelines, migrations, and AI agent runs * `progress`: best for tracking real-time progress with percentage, like tasks, backups, migrations, syncs, or uploads * `alert`: best for status updates, such as feature adoption, reactivation, onboarding blockers, incidents, escalations, and other operational states * `timer`: use it when you need countdowns or timers ### Start & Update Live Activity Use a stable `streamKey` to identify the metric, job, deployment, or system you want to keep visible. The first `stream(...)` call starts the Live Activity. Later calls with the same `streamKey` update it. #### Stats

Stats Live Activity stream example

```php theme={null} $activitysmith->liveActivities->stream( 'sales-hourly', contentState: LiveActivityContentState::make( title: 'Sales', subtitle: 'last hour', type: 'stats', metrics: [ LiveActivityMetric::make(label: 'Revenue', value: '$2430', color: 'blue'), LiveActivityMetric::make(label: 'Orders', value: '37', color: 'green'), LiveActivityMetric::make(label: 'Conversion', value: '4.8%', color: 'magenta'), LiveActivityMetric::make(label: 'Avg Order', value: '$65.68', color: 'yellow'), LiveActivityMetric::make(label: 'Refunds', value: '$84', color: 'red'), LiveActivityMetric::make(label: 'New Buyers', value: '18', color: 'cyan'), ], ), ); ``` #### Metrics

Metrics Live Activity stream example

```php theme={null} $activitysmith->liveActivities->stream( 'prod-web-1', contentState: LiveActivityContentState::make( title: 'Server Health', subtitle: 'prod-web-1', type: 'metrics', metrics: [ LiveActivityMetric::make(label: 'CPU', value: 9, unit: '%'), LiveActivityMetric::make(label: 'MEM', value: 45, unit: '%'), ], ), ); ``` #### Segmented Progress

Segmented Progress Live Activity stream example

```php theme={null} $activitysmith->liveActivities->stream( 'nightly-backup', contentState: LiveActivityContentState::make( title: 'Nightly Backup', subtitle: 'upload archive', type: 'segmented_progress', numberOfSteps: 3, currentStep: 2, ), ); ``` #### Progress

Progress Live Activity stream example

```php theme={null} $activitysmith->liveActivities->stream( 'search-reindex', contentState: LiveActivityContentState::make( title: 'Search Reindex', subtitle: 'catalog-v2', type: 'progress', percentage: 42, ), ); ``` #### Alert

Alert Live Activity stream example

```php theme={null} $activitysmith->liveActivities->stream( 'customer-ops', contentState: LiveActivityContentState::make( title: 'Reactivation', message: 'Lumen came back after 2 weeks', type: 'alert', icon: LiveActivityAlertIcon::make(symbol: 'cloud.sun', color: 'yellow'), badge: LiveActivityAlertBadge::make(title: 'Customer', color: 'magenta'), ), ); ``` #### Timer

Timer Live Activity stream example

```php theme={null} $activitysmith->liveActivities->stream( 'benchmark-run', contentState: LiveActivityContentState::make( title: 'Benchmark Run', subtitle: 'sampling', type: 'timer', durationSeconds: 300, color: 'cyan', ), ); ``` For a countdown, send `durationSeconds`. You can update `title`, `subtitle`, `color`, or any other visible field as the work changes. Leave `durationSeconds` out unless you want to change the timer. To start at 00:00 and count up, set `countsDown` to `false` and leave out `durationSeconds`. ### End Live Activity Call `endStream(...)` with the same `streamKey` 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 `autoDismissMinutes` to choose a different dismissal time, including `0` for immediate dismissal. ```php theme={null} $activitysmith->liveActivities->endStream( 'prod-web-1', contentState: LiveActivityContentState::make( title: 'Server Health', subtitle: 'prod-web-1', type: 'metrics', metrics: [ LiveActivityMetric::make(label: 'CPU', value: 7, unit: '%'), LiveActivityMetric::make(label: 'MEM', value: 38, unit: '%'), ], autoDismissMinutes: 2, ), ); ``` ### Icons and Badges Add more context to Live Activities with icons and badges. #### Icon Supported Live Activity types: `stats`, `metrics`, `progress`, `segmented_progress`, `alert`, and `timer`.

Metrics Live Activity with an SF Symbol icon on the iPhone Lock Screen

```php theme={null} $activitysmith->liveActivities->stream( 'prod-web-1', contentState: LiveActivityContentState::make( title: 'Server Health', subtitle: 'prod-web-1', type: LiveActivities::TYPE_METRICS, icon: LiveActivityAlertIcon::make(symbol: 'server.rack', color: 'blue'), metrics: [ LiveActivityMetric::make(label: 'CPU', value: 18, unit: '%'), LiveActivityMetric::make(label: 'MEM', value: 42, unit: '%'), ], ), ); ``` The `icon` symbol value is an Apple SF Symbol name. Browse the catalog with one of these tools: * [ActivitySmith app](https://apps.apple.com/us/app/activitysmith/id6752254835) - Open Settings -> SF Symbols to browse 45 hand-picked icons ready to use * [SF Symbols](https://developer.apple.com/sf-symbols/) - Apple's official macOS app * [Interactful](https://apps.apple.com/app/interactful/id1528095640) - free third-party iOS app listing all SF Symbols under Foundations -> Iconography #### Badge Badges are supported by `alert`, `progress`, and `segmented_progress` Live Activities.

Progress Live Activity with a badge on the iPhone Lock Screen

```php theme={null} $activitysmith->liveActivities->stream( 'nightly-database-backup', contentState: LiveActivityContentState::make( title: 'Nightly Database Backup', subtitle: 'verify restore', type: LiveActivities::TYPE_PROGRESS, badge: LiveActivityAlertBadge::make(title: 'S3', color: 'cyan'), percentage: 62, ), ); ``` ### Live Activity Colors Choose from these colors for the Live Activity accent, including progress bars and action buttons, or apply them to an individual icon or badge: `lime`, `green`, `cyan`, `blue`, `purple`, `magenta`, `red`, `orange`, `yellow`, `gray` ### Live Activity Action

Metrics Live Activity with action

Live Activities can include an action button. * `open_url`: open an HTTPS URL. * `open_url` with a `shortcuts://run-shortcut?name=...` URL: run a specific iPhone Shortcut, for example to open an app. * `webhook`: trigger a backend GET/POST workflow. #### Open URL action ```php theme={null} $activitysmith->liveActivities->stream( 'prod-web-1', contentState: LiveActivityContentState::make( title: 'Server Health', subtitle: 'prod-web-1', type: 'metrics', metrics: [ LiveActivityMetric::make(label: 'CPU', value: 76, unit: '%'), LiveActivityMetric::make(label: 'MEM', value: 52, unit: '%'), ], ), action: LiveActivityAction::make( title: 'Dashboard', type: 'open_url', url: 'https://status.example.com/servers/prod-web-1', ), ); ``` #### Apple Shortcut action ```php theme={null} $activitysmith->liveActivities->stream( 'prod-web-1', contentState: LiveActivityContentState::make( title: 'Server Health', subtitle: 'prod-web-1', type: 'metrics', metrics: [ LiveActivityMetric::make(label: 'CPU', value: 76, unit: '%'), LiveActivityMetric::make(label: 'MEM', value: 52, unit: '%'), ], ), action: LiveActivityAction::make( title: 'Chat with Jarvis', type: 'open_url', url: 'shortcuts://run-shortcut?name=Jarvis', ), ); ``` #### Webhook action ```php theme={null} $activitysmith->liveActivities->stream( 'search-reindex', contentState: LiveActivityContentState::make( title: 'Reindexing product search', subtitle: 'Shard 7 of 12', type: 'segmented_progress', numberOfSteps: 12, currentStep: 7, ), action: LiveActivityAction::make( 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-php', ], ), ); ``` #### Secondary action ![Alert Live Activity with primary and secondary action buttons](https://cdn.activitysmith.com/features/live-activity-secondary-action.png) Use `secondary_action` when you want a second button beside the primary `action`. The secondary action button is supported for `alert`, `progress`, and `segmented_progress` Live Activities. Both buttons use the same `open_url`, `webhook`, and Apple Shortcut payload shapes. ```php theme={null} $activitysmith->liveActivities->stream( 'agent-approval', contentState: LiveActivityContentState::make( title: 'Approval Needed', message: 'Should I send the follow-up email to Brightlane?', type: 'alert', color: 'green', icon: LiveActivityAlertIcon::make(symbol: 'sparkles', color: 'green'), badge: LiveActivityAlertBadge::make(title: 'Agent', color: 'green'), ), action: LiveActivityAction::make( title: 'Send', type: 'webhook', url: 'https://agent.example.com/live-activity/approve', method: 'POST', body: [ 'approval_id' => 'approval_01JY3J7Q9S0P8M1V5PZK7DR4M2', 'decision' => 'send', ], ), secondaryAction: LiveActivityAction::make( title: 'Deny', type: 'webhook', url: 'https://agent.example.com/live-activity/deny', method: 'POST', body: [ 'approval_id' => 'approval_01JY3J7Q9S0P8M1V5PZK7DR4M2', 'decision' => 'deny', ], ), ); ``` ## Channels Target specific channels when sending a push notification or streaming a Live Activity. ```php PHP theme={null} $activitysmith->notifications->send( title: 'New subscription 💸', message: 'Customer upgraded to Pro plan', channels: ['ios-builds', 'engineering'], ); $activitysmith->liveActivities->stream( 'nightly-backup', contentState: LiveActivityContentState::make( title: 'Nightly database backup', type: 'segmented_progress', numberOfSteps: 3, currentStep: 1, ), channels: ['ios-builds'], ); ``` ## Widgets

Lock screen widgets

ActivitySmith lets you display any value on your Lock Screen with widgets - SaaS metrics, revenue, signups, uptime, habits, or anything else you want to track. Create a metric in the web app, then update the metric value using our API, add a widget to your lock screen and it will fetch the latest update automatically.

Create widget metric

Use the metric key to update its value. ```php theme={null} $activitysmith->metrics->update('deploy.success_rate', 99.9); ``` String metric values work too. ```php theme={null} $activitysmith->metrics->update('prod.status', 'healthy'); ``` ## Error Handling Wrap SDK calls with `try/catch`: ```php PHP theme={null} try { $activitysmith->notifications->send(title: 'Hello'); } catch (\Throwable $error) { echo $error->getMessage(); } ``` ## Additional Resources Install the ActivitySmith PHP SDK from Packagist View the PHP SDK source on GitHub # Python Source: https://activitysmith.com/docs/sdks/python Use the ActivitySmith Python SDK to send push notifications and Live Activity progress updates from Python scripts, jobs, and backend services. ## Installation Install the ActivitySmith Python SDK with pip: ```python Python theme={null} pip install activitysmith ``` ## Usage 1. [Create an API key](https://activitysmith.com/app/keys) 2. Set `ACTIVITYSMITH_API_KEY` or pass it directly to `ActivitySmith`. 3. Reuse the client anywhere you send pushes or Live Activity updates. Create the client once: ```python Python theme={null} import os from activitysmith import ( ActivitySmith, action, alert_badge, alert_icon, content_state, metric, ) activitysmith = ActivitySmith(api_key=os.environ.get("ACTIVITYSMITH_API_KEY", "YOUR-API-KEY")) ``` ### Send a Push Notification Use `activitysmith.notifications.send` when a deploy finishes, a customer upgrades, or a background job needs attention. `title` is required. `message` and `subtitle` are optional. Push notification example for a new subscription event ```python Python theme={null} activitysmith.notifications.send( title="New subscription 💸", message="Customer upgraded to Pro plan", ) ``` ### Rich Push Notifications with Media Rich push notification with image ```python Python theme={null} activitysmith.notifications.send( title="Homepage ready", message="Your agent finished the redesign.", media="https://cdn.example.com/output/homepage-v2.png", redirection="https://github.com/acme/web/pull/482", ) ``` Send images, videos, or audio with your push notifications, press and hold to preview media directly from the notification, then tap through to open the linked content. Rich push notification with audio What will work: * direct image URL: `.jpg`, `.png`, `.gif`, etc. * direct audio file URL: `.mp3`, `.m4a`, etc. * direct video file URL: `.mp4`, `.mov`, etc. * URL that responds with a proper media `Content-Type`, even if the path has no extension `media` can be combined with `redirection`, but not with `actions`. `redirection` can be an HTTPS URL or a `shortcuts://run-shortcut?name=...` URL. ### Actionable Push Notifications Actionable push notification with redirection and actions Push notification redirection can open an HTTPS URL or run a specific iPhone Shortcut with a `shortcuts://run-shortcut?name=...` URL when someone taps the notification. For expanded notification actions, `open_url` supports HTTPS URLs and `shortcuts://run-shortcut?name=...` URLs. Webhooks are executed by the ActivitySmith backend and must use HTTPS. ```python Python theme={null} activitysmith.notifications.send( title="New subscription 💸", message="Customer upgraded to Pro plan", redirection="https://crm.example.com/customers/cus_9f3a1d", actions=[ action( title="Open CRM", type="open_url", url="https://crm.example.com/customers/cus_9f3a1d", ), action( title="Chat with Jarvis", type="open_url", url="shortcuts://run-shortcut?name=Jarvis", ), action( title="Start Onboarding Workflow", type="webhook", url="https://hooks.example.com/activitysmith/onboarding/start", method="POST", body={ "customer_id": "cus_9f3a1d", "plan": "pro", }, ), ], ) ``` ## Live Activities There are six types of Live Activities: * `stats`: best for showing business numbers side by side, such as revenue, sales, new users, conversion, refunds, or any other value you want visible at a glance * `metrics`: best for live percentage values that change often, like server CPU, memory usage, disk usage, or error rate * `segmented_progress`: best for anything that moves through clear stages, like deployments, onboarding flows, backups, ETL pipelines, migrations, and AI agent runs * `progress`: best for tracking real-time progress with percentage, like tasks, backups, migrations, syncs, or uploads * `alert`: best for status updates, such as feature adoption, reactivation, onboarding blockers, incidents, escalations, and other operational states * `timer`: use it when you need countdowns or timers ### Start & Update Live Activity Use a stable `stream_key` to identify the metric, job, deployment, or system you want to keep visible. The first `stream(...)` call starts the Live Activity. Later calls with the same `stream_key` update it. #### Stats

Stats Live Activity stream example

```python theme={null} activitysmith.live_activities.stream( "sales-hourly", content_state=content_state( title="Sales", subtitle="last hour", type="stats", metrics=[ metric(label="Revenue", value="$2430", color="blue"), metric(label="Orders", value="37", color="green"), metric(label="Conversion", value="4.8%", color="magenta"), metric(label="Avg Order", value="$65.68", color="yellow"), metric(label="Refunds", value="$84", color="red"), metric(label="New Buyers", value="18", color="cyan"), ], ), ) ``` #### Metrics

Metrics Live Activity stream example

```python theme={null} activitysmith.live_activities.stream( "prod-web-1", content_state=content_state( title="Server Health", subtitle="prod-web-1", type="metrics", metrics=[ metric(label="CPU", value=9, unit="%"), metric(label="MEM", value=45, unit="%"), ], ), ) ``` #### Segmented Progress

Segmented Progress Live Activity stream example

```python theme={null} activitysmith.live_activities.stream( "nightly-backup", content_state=content_state( title="Nightly Backup", subtitle="upload archive", type="segmented_progress", number_of_steps=3, current_step=2, ), ) ``` #### Progress

Progress Live Activity stream example

```python theme={null} activitysmith.live_activities.stream( "search-reindex", content_state=content_state( title="Search Reindex", subtitle="catalog-v2", type="progress", percentage=42, ), ) ``` #### Alert

Alert Live Activity stream example

```python theme={null} activitysmith.live_activities.stream( "customer-ops", content_state=content_state( title="Reactivation", message="Lumen came back after 2 weeks", type="alert", icon=alert_icon("cloud.sun", color="yellow"), badge=alert_badge("Customer", color="magenta"), ), ) ``` #### Timer

Timer Live Activity stream example

```python theme={null} activitysmith.live_activities.stream( "benchmark-run", content_state=content_state( title="Benchmark Run", subtitle="sampling", type="timer", duration_seconds=300, color="cyan", ), ) ``` For a countdown, send `duration_seconds`. You can update `title`, `subtitle`, `color`, or any other visible field as the work changes. Leave `duration_seconds` out unless you want to change the timer. To start at 00:00 and count up, set `counts_down=False` and leave out `duration_seconds`. ### End Live Activity Call `end_stream(...)` with the same `stream_key` 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. ```python theme={null} activitysmith.live_activities.end_stream( "prod-web-1", content_state=content_state( title="Server Health", subtitle="prod-web-1", type="metrics", metrics=[ metric(label="CPU", value=7, unit="%"), metric(label="MEM", value=38, unit="%"), ], auto_dismiss_minutes=2, ), ) ``` ### Icons and Badges Add more context to Live Activities with icons and badges. #### Icon Supported Live Activity types: `stats`, `metrics`, `progress`, `segmented_progress`, `alert`, and `timer`.

Metrics Live Activity with an SF Symbol icon on the iPhone Lock Screen

```python theme={null} activitysmith.live_activities.stream( "prod-web-1", content_state=content_state( title="Server Health", subtitle="prod-web-1", type=activitysmith.live_activities.TYPE_METRICS, icon=alert_icon("server.rack", color="blue"), metrics=[ metric(label="CPU", value=18, unit="%"), metric(label="MEM", value=42, unit="%"), ], ), ) ``` The `icon.symbol` value is an Apple SF Symbol name. Browse the catalog with one of these tools: * [ActivitySmith app](https://apps.apple.com/us/app/activitysmith/id6752254835) - Open Settings -> SF Symbols to browse 45 hand-picked icons ready to use * [SF Symbols](https://developer.apple.com/sf-symbols/) - Apple's official macOS app * [Interactful](https://apps.apple.com/app/interactful/id1528095640) - free third-party iOS app listing all SF Symbols under Foundations -> Iconography #### Badge Badges are supported by `alert`, `progress`, and `segmented_progress` Live Activities.

Progress Live Activity with a badge on the iPhone Lock Screen

```python theme={null} activitysmith.live_activities.stream( "nightly-database-backup", content_state=content_state( title="Nightly Database Backup", subtitle="verify restore", type=activitysmith.live_activities.TYPE_PROGRESS, badge=alert_badge("S3", color="cyan"), percentage=62, ), ) ``` ### Live Activity Colors Choose from these colors for the Live Activity accent, including progress bars and action buttons, or apply them to an individual icon or badge: `lime`, `green`, `cyan`, `blue`, `purple`, `magenta`, `red`, `orange`, `yellow`, `gray` ### Live Activity Action

Metrics Live Activity with action

Live Activities can include an action button. * `open_url`: open an HTTPS URL. * `open_url` with a `shortcuts://run-shortcut?name=...` URL: run a specific iPhone Shortcut, for example to open an app. * `webhook`: trigger a backend GET/POST workflow. #### Open URL action ```python theme={null} activitysmith.live_activities.stream( "prod-web-1", content_state=content_state( title="Server Health", subtitle="prod-web-1", type="metrics", metrics=[ metric(label="CPU", value=76, unit="%"), metric(label="MEM", value=52, unit="%"), ], ), action=action( title="Dashboard", type="open_url", url="https://status.example.com/servers/prod-web-1", ), ) ``` #### Apple Shortcut action ```python theme={null} activitysmith.live_activities.stream( "prod-web-1", content_state=content_state( title="Server Health", subtitle="prod-web-1", type="metrics", metrics=[ metric(label="CPU", value=76, unit="%"), metric(label="MEM", value=52, unit="%"), ], ), action=action( title="Chat with Jarvis", type="open_url", url="shortcuts://run-shortcut?name=Jarvis", ), ) ``` #### Webhook action ```python theme={null} activitysmith.live_activities.stream( "search-reindex", content_state=content_state( title="Reindexing product search", subtitle="Shard 7 of 12", type="segmented_progress", number_of_steps=12, current_step=7, ), action=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-python", }, ), ) ``` #### Secondary action ![Alert Live Activity with primary and secondary action buttons](https://cdn.activitysmith.com/features/live-activity-secondary-action.png) Use `secondary_action` when you want a second button beside the primary `action`. The secondary action button is supported for `alert`, `progress`, and `segmented_progress` Live Activities. Both buttons use the same `open_url`, `webhook`, and Apple Shortcut payload shapes. ```python theme={null} activitysmith.live_activities.stream( "agent-approval", content_state=content_state( title="Approval Needed", message="Should I send the follow-up email to Brightlane?", type="alert", color="green", icon=alert_icon("sparkles", color="green"), badge=alert_badge("Agent", color="green"), ), action=action( title="Send", type="webhook", url="https://agent.example.com/live-activity/approve", method="POST", body={ "approval_id": "approval_01JY3J7Q9S0P8M1V5PZK7DR4M2", "decision": "send", }, ), secondary_action=action( title="Deny", type="webhook", url="https://agent.example.com/live-activity/deny", method="POST", body={ "approval_id": "approval_01JY3J7Q9S0P8M1V5PZK7DR4M2", "decision": "deny", }, ), ) ``` ## Channels Target specific channels when sending a push notification or streaming a Live Activity. ```python Python theme={null} activitysmith.notifications.send( title="New subscription 💸", message="Customer upgraded to Pro plan", channels=["ios-builds", "engineering"], ) activitysmith.live_activities.stream( "nightly-backup", content_state=content_state( title="Nightly database backup", type="segmented_progress", number_of_steps=3, current_step=1, ), channels=["ios-builds"], ) ``` ## Widgets

Lock screen widgets

ActivitySmith lets you display any value on your Lock Screen with widgets - SaaS metrics, revenue, signups, uptime, habits, or anything else you want to track. Create a metric in the web app, then update the metric value using our API, add a widget to your lock screen and it will fetch the latest update automatically.

Create widget metric

Use the metric key to update its value. ```python theme={null} activitysmith.metrics.update("deploy.success_rate", 99.9) ``` String metric values work too. ```python theme={null} activitysmith.metrics.update("prod.status", "healthy") ``` ## Error Handling Wrap API calls with `try/except`. The SDK raises exceptions for non-2xx responses. Rate limit errors use the `error` and `message` fields, and Live Activity limit errors include `limit` and `active`. See [Rate Limits](/docs/rate-limits) for details. ## Additional Resources Install the ActivitySmith Python SDK from PyPI View the Python SDK source on GitHub # Ruby Source: https://activitysmith.com/docs/sdks/ruby Use the ActivitySmith Ruby SDK to send push notifications and Live Activity progress updates from Ruby apps, workers, and scheduled jobs. ## Installation Install the ActivitySmith Ruby SDK with RubyGems: ```ruby Ruby theme={null} gem install activitysmith ``` ## Usage 1. [Create an API key](https://activitysmith.com/app/keys) 2. Set `ACTIVITYSMITH_API_KEY` or pass it directly to `ActivitySmith::Client`. 3. Reuse the client anywhere you send pushes or Live Activity updates. Create the client once: ```ruby Ruby theme={null} require "activitysmith" api_key = ENV["ACTIVITYSMITH_API_KEY"] || "YOUR-API-KEY" activitysmith = ActivitySmith::Client.new(api_key: api_key) ``` ### Send a Push Notification Use `activitysmith.notifications.send` when a deploy finishes, a customer upgrades, or a background job needs attention. `title` is required. `message` and `subtitle` are optional. Push notification example for a new subscription event ```ruby Ruby theme={null} activitysmith.notifications.send( { title: "New subscription 💸", message: "Customer upgraded to Pro plan" } ) ``` ### Rich Push Notifications with Media Rich push notification with image ```ruby Ruby theme={null} activitysmith.notifications.send( { title: "Homepage ready", message: "Your agent finished the redesign.", media: "https://cdn.example.com/output/homepage-v2.png", redirection: "https://github.com/acme/web/pull/482" } ) ``` Send images, videos, or audio with your push notifications, press and hold to preview media directly from the notification, then tap through to open the linked content. Rich push notification with audio What will work: * direct image URL: `.jpg`, `.png`, `.gif`, etc. * direct audio file URL: `.mp3`, `.m4a`, etc. * direct video file URL: `.mp4`, `.mov`, etc. * URL that responds with a proper media `Content-Type`, even if the path has no extension `media` can be combined with `redirection`, but not with `actions`. `redirection` can be an HTTPS URL or a `shortcuts://run-shortcut?name=...` URL. ### Actionable Push Notifications Actionable push notification with redirection and actions Push notification redirection can open an HTTPS URL or run a specific iPhone Shortcut with a `shortcuts://run-shortcut?name=...` URL when someone taps the notification. For expanded notification actions, `open_url` supports HTTPS URLs and `shortcuts://run-shortcut?name=...` URLs. Webhooks are executed by the ActivitySmith backend and must use HTTPS. ```ruby Ruby theme={null} activitysmith.notifications.send( { title: "New subscription 💸", message: "Customer upgraded to Pro plan", redirection: "https://crm.example.com/customers/cus_9f3a1d", actions: [ { title: "Open CRM", type: "open_url", url: "https://crm.example.com/customers/cus_9f3a1d" }, { title: "Chat with Jarvis", type: "open_url", url: "shortcuts://run-shortcut?name=Jarvis" }, { title: "Start Onboarding Workflow", type: "webhook", url: "https://hooks.example.com/activitysmith/onboarding/start", method: "POST", body: { customer_id: "cus_9f3a1d", plan: "pro" } } ] } ) ``` ## Live Activities There are six types of Live Activities: * `stats`: best for showing business numbers side by side, such as revenue, sales, new users, conversion, refunds, or any other value you want visible at a glance * `metrics`: best for live percentage values that change often, like server CPU, memory usage, disk usage, or error rate * `segmented_progress`: best for anything that moves through clear stages, like deployments, onboarding flows, backups, ETL pipelines, migrations, and AI agent runs * `progress`: best for tracking real-time progress with percentage, like tasks, backups, migrations, syncs, or uploads * `alert`: best for status updates, such as feature adoption, reactivation, onboarding blockers, incidents, escalations, and other operational states * `timer`: use it when you need countdowns or timers ### Start & Update Live Activity Use a stable `stream_key` to identify the metric, job, deployment, or system you want to keep visible. The first `stream(...)` call starts the Live Activity. Later calls with the same `stream_key` update it. #### Stats

Stats Live Activity stream example

```ruby theme={null} activitysmith.live_activities.stream( "sales-hourly", { content_state: { title: "Sales", subtitle: "last hour", type: "stats", metrics: [ { label: "Revenue", value: "$2430", color: "blue" }, { label: "Orders", value: "37", color: "green" }, { label: "Conversion", value: "4.8%", color: "magenta" }, { label: "Avg Order", value: "$65.68", color: "yellow" }, { label: "Refunds", value: "$84", color: "red" }, { label: "New Buyers", value: "18", color: "cyan" } ] } } ) ``` #### Metrics

Metrics Live Activity stream example

```ruby theme={null} activitysmith.live_activities.stream( "prod-web-1", { content_state: { title: "Server Health", subtitle: "prod-web-1", type: "metrics", metrics: [ { label: "CPU", value: 9, unit: "%" }, { label: "MEM", value: 45, unit: "%" } ] } } ) ``` #### Segmented Progress

Segmented Progress Live Activity stream example

```ruby theme={null} activitysmith.live_activities.stream( "nightly-backup", { content_state: { title: "Nightly Backup", subtitle: "upload archive", type: "segmented_progress", number_of_steps: 3, current_step: 2 } } ) ``` #### Progress

Progress Live Activity stream example

```ruby theme={null} activitysmith.live_activities.stream( "search-reindex", { content_state: { title: "Search Reindex", subtitle: "catalog-v2", type: "progress", percentage: 42 } } ) ``` #### Alert

Alert Live Activity stream example

```ruby theme={null} activitysmith.live_activities.stream( "customer-ops", { content_state: ActivitySmith::LiveActivities.content_state( title: "Reactivation", message: "Lumen came back after 2 weeks", type: ActivitySmith::LiveActivities::TYPE_ALERT, icon: ActivitySmith::LiveActivities.alert_icon("cloud.sun", color: "yellow"), badge: ActivitySmith::LiveActivities.alert_badge("Customer", color: "magenta") ) } ) ``` #### Timer

Timer Live Activity stream example

```ruby theme={null} activitysmith.live_activities.stream( "benchmark-run", { content_state: { title: "Benchmark Run", subtitle: "sampling", type: "timer", duration_seconds: 300, color: "cyan" } } ) ``` For a countdown, send `duration_seconds`. You can update `title`, `subtitle`, `color`, or any other visible field as the work changes. Leave `duration_seconds` out unless you want to change the timer. To start at 00:00 and count up, set `counts_down: false` and leave out `duration_seconds`. ### End Live Activity Call `end_stream(...)` with the same `stream_key` 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. ```ruby theme={null} activitysmith.live_activities.end_stream( "prod-web-1", { 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 } } ) ``` ### Icons and Badges Add more context to Live Activities with icons and badges. #### Icon Supported Live Activity types: `stats`, `metrics`, `progress`, `segmented_progress`, `alert`, and `timer`.

Metrics Live Activity with an SF Symbol icon on the iPhone Lock Screen

```ruby theme={null} activitysmith.live_activities.stream( "prod-web-1", { content_state: ActivitySmith::LiveActivities.content_state( title: "Server Health", subtitle: "prod-web-1", type: "metrics", icon: ActivitySmith::LiveActivities.alert_icon("server.rack", color: "blue"), metrics: [ { label: "CPU", value: 18, unit: "%" }, { label: "MEM", value: 42, unit: "%" } ] ) } ) ``` The `icon` symbol value is an Apple SF Symbol name. Browse the catalog with one of these tools: * [ActivitySmith app](https://apps.apple.com/us/app/activitysmith/id6752254835) - Open Settings -> SF Symbols to browse 45 hand-picked icons ready to use * [SF Symbols](https://developer.apple.com/sf-symbols/) - Apple's official macOS app * [Interactful](https://apps.apple.com/app/interactful/id1528095640) - free third-party iOS app listing all SF Symbols under Foundations -> Iconography #### Badge Badges are supported by `alert`, `progress`, and `segmented_progress` Live Activities.

Progress Live Activity with a badge on the iPhone Lock Screen

```ruby theme={null} activitysmith.live_activities.stream( "nightly-database-backup", { content_state: ActivitySmith::LiveActivities.content_state( title: "Nightly Database Backup", subtitle: "verify restore", type: "progress", badge: ActivitySmith::LiveActivities.alert_badge("S3", color: "cyan"), percentage: 62 ) } ) ``` ### Live Activity Colors Choose from these colors for the Live Activity accent, including progress bars and action buttons, or apply them to an individual icon or badge: `lime`, `green`, `cyan`, `blue`, `purple`, `magenta`, `red`, `orange`, `yellow`, `gray` ### Live Activity Action

Metrics Live Activity with action

Live Activities can include an action button. * `open_url`: open an HTTPS URL. * `open_url` with a `shortcuts://run-shortcut?name=...` URL: run a specific iPhone Shortcut, for example to open an app. * `webhook`: trigger a backend GET/POST workflow. #### Open URL action ```ruby theme={null} activitysmith.live_activities.stream( "prod-web-1", { content_state: { title: "Server Health", subtitle: "prod-web-1", type: "metrics", metrics: [ { label: "CPU", value: 76, unit: "%" }, { label: "MEM", value: 52, unit: "%" } ] }, action: { title: "Dashboard", type: "open_url", url: "https://status.example.com/servers/prod-web-1" } } ) ``` #### Apple Shortcut action ```ruby theme={null} activitysmith.live_activities.stream( "prod-web-1", { content_state: { title: "Server Health", subtitle: "prod-web-1", type: "metrics", metrics: [ { label: "CPU", value: 76, unit: "%" }, { label: "MEM", value: 52, unit: "%" } ] }, action: { title: "Chat with Jarvis", type: "open_url", url: "shortcuts://run-shortcut?name=Jarvis" } } ) ``` #### Webhook action ```ruby theme={null} activitysmith.live_activities.stream( "search-reindex", { content_state: { title: "Reindexing product search", subtitle: "Shard 7 of 12", type: "segmented_progress", 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-ruby" } } } ) ``` #### Secondary action ![Alert Live Activity with primary and secondary action buttons](https://cdn.activitysmith.com/features/live-activity-secondary-action.png) Use `secondary_action` when you want a second button beside the primary `action`. The secondary action button is supported for `alert`, `progress`, and `segmented_progress` Live Activities. Both buttons use the same `open_url`, `webhook`, and Apple Shortcut payload shapes. ```ruby theme={null} activitysmith.live_activities.stream( "agent-approval", { content_state: ActivitySmith::LiveActivities.content_state( title: "Approval Needed", message: "Should I send the follow-up email to Brightlane?", type: "alert", color: "green", icon: ActivitySmith::LiveActivities.alert_icon("sparkles", color: "green"), badge: ActivitySmith::LiveActivities.alert_badge("Agent", color: "green") ), action: { title: "Send", type: "webhook", url: "https://agent.example.com/live-activity/approve", method: "POST", body: { approval_id: "approval_01JY3J7Q9S0P8M1V5PZK7DR4M2", decision: "send" } }, secondary_action: { title: "Deny", type: "webhook", url: "https://agent.example.com/live-activity/deny", method: "POST", body: { approval_id: "approval_01JY3J7Q9S0P8M1V5PZK7DR4M2", decision: "deny" } } } ) ``` ## Channels Target specific channels when sending a push notification or streaming a Live Activity. ```ruby Ruby theme={null} activitysmith.notifications.send( { title: "New subscription 💸", message: "Customer upgraded to Pro plan", channels: ["ios-builds", "engineering"] } ) activitysmith.live_activities.stream( "nightly-backup", { channels: ["ios-builds"], content_state: { title: "Nightly database backup", number_of_steps: 3, current_step: 1, type: "segmented_progress" } } ) ``` ## Widgets

Lock screen widgets

ActivitySmith lets you display any value on your Lock Screen with widgets - SaaS metrics, revenue, signups, uptime, habits, or anything else you want to track. Create a metric in the web app, then update the metric value using our API, add a widget to your lock screen and it will fetch the latest update automatically.

Create widget metric

Use the metric key to update its value. ```ruby theme={null} activitysmith.metrics.update("deploy.success_rate", 99.9) ``` String metric values work too. ```ruby theme={null} activitysmith.metrics.update("prod.status", "healthy") ``` ## Error Handling Handle API errors with `begin/rescue` around SDK calls: ```ruby Ruby theme={null} begin activitysmith.notifications.send( { title: "Hello" } ) rescue OpenapiClient::ApiError => err puts "Request failed: #{err.code} #{err.message}" end ``` ## Additional Resources Install the ActivitySmith Ruby SDK from RubyGems View the Ruby SDK source on GitHub # Team Members Source: https://activitysmith.com/docs/team Manage your team from one place: invite members, track pending invites, and remove access. Team Members ## Managing Team Members The **Members** page is where team owners manage access for the whole workspace. You can: * Invite one or many people at once * See active users and their role * Track pending invitations and expiration dates * Remove members when they no longer need access ## Roles ActivitySmith currently supports two team roles: | Role | Access | | -------- | ------------------------------------------------------------- | | `owner` | Full access, including inviting and removing members | | `member` | Standard workspace access without team management permissions | ## Invite Team Members Only team owners can invite new members. 1. Open your ActivitySmith dashboard. 2. Go to **Members** in the left sidebar. 3. Click **Invite members**. 4. Enter one or more email addresses in the invite modal. 5. Separate multiple emails with commas or new lines. 6. Click **Send Invites**. Invite Team Members Newly invited users appear in the **Invited users** table with: * `pending` status until accepted * Invite date (`Invited`) * Expiration date (`Expires`) Members are added to **Active users** only after they accept the invite. ## Remove a Member Only team owners can remove members. 1. Open **Members**. 2. Find the user in **Active users**. 3. Click **Remove** in the **Actions** column. 4. Confirm the removal. The removed member loses team access immediately. # Widgets Source: https://activitysmith.com/docs/widgets ActivitySmith lets you display any value on your Lock Screen with widgets - SaaS metrics, revenue, signups, uptime, habits, or anything else you want to track. ActivitySmith Lock Screen widgets ## How It Works 1. Create a metric in the web app. 2. Update the value using API anytime it changes. 3. Add the widget to your iPhone Lock Screen. 4. The widget fetches the latest value about every 15 minutes. iOS manages the refresh schedule. When creating a metric, you can choose the format: number, currency, percent, unit, or string. Create a widget metric in ActivitySmith ## Updating Metric Value Use the metric key when sending updates. Values can be numbers or strings. ```js Node theme={null} import ActivitySmith from "activitysmith"; const activitysmith = new ActivitySmith({ apiKey: process.env.ACTIVITYSMITH_API_KEY, }); await activitysmith.metrics.update("deploy.success_rate", 99.9); ``` ```python Python theme={null} import os from activitysmith import ActivitySmith activitysmith = ActivitySmith(api_key=os.environ["ACTIVITYSMITH_API_KEY"]) activitysmith.metrics.update("deploy.success_rate", 99.9) ``` ```go Go theme={null} package main import ( "log" activitysmithsdk "github.com/ActivitySmithHQ/activitysmith-go" ) func main() { activitysmith, err := activitysmithsdk.New("YOUR-API-KEY") if err != nil { log.Fatal(err) } _, err = activitysmith.Metrics.Update("deploy.success_rate", 99.9) if err != nil { log.Fatal(err) } } ``` ```php PHP theme={null} metrics->update('deploy.success_rate', 99.9); ``` ```ruby Ruby theme={null} require "activitysmith" activitysmith = ActivitySmith::Client.new(api_key: ENV.fetch("ACTIVITYSMITH_API_KEY")) activitysmith.metrics.update("deploy.success_rate", 99.9) ``` ```bash cURL theme={null} curl -X POST "https://activitysmith.com/api/metrics/deploy.success_rate/value" \ -H "Authorization: Bearer $ACTIVITYSMITH_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "value": 99.9 }' ``` For the full API reference, see [Update Metric Value](/docs/api-reference/endpoint/metric-value-update).