Quick start
Start, launch, update, and end a Live Activity.
You need three things: a way to make HTTP requests (curl, a backend, a serverless function), an API key (creating an account mints one automatically), and an iPhone with the Web Live Activities app or an Android phone with the companion app.
Every call needs the API key in the x-api-key header. The key is confidential: send requests from the service's backend, never from browser code.
Start the activity
Send the initial state. The layout field inside it picks the type (progress, picture, versus, or countdown); the rest of state is what gets shown. brand.title names the activity's row in the app. Every call also carries a required widgetContainerId: any text naming the widget container the activity belongs to.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
curl -X POST https://api.webliveactivity.com/api/start \ -H 'Content-Type: application/json' \ -H 'x-api-key: wla_your_key' \ -d '{ "state": { "layout": "progress", "primaryText": "Preparing your order", "progress": 0.25 }, "brand": { "title": "Order #1234" }, "widgetContainerId": "pizza-tracker" }'
The response returns an activityId (the handle every later call targets) and three ready launch links:
1 2 3 4 5 6 7 8 9 10 11
{ "ok": true, "activityId": "act-8f2c1a", "group": "", "widgetContainerId": "pizza-tracker", "links": { "iframe": "<iframe src=\"https://webliveactivity.com/embed/button?type=track&userId=act-8f2c1a\" width=\"340\" height=\"95\" style=\"border:0;color-scheme:light\"></iframe>", "redirect": "https://webliveactivity.com/clip/act-8f2c1a", "qr": "https://webliveactivity.com/embed/qr?type=track&userId=act-8f2c1a" } }
Open it on a phone
No website needed: open links.qr on any screen and scan it with the phone.
On a page, paste links.iframe. It renders a Track With Live Activity button. A tap opens the app (or its instant, install-free launch) and the activity appears on the Lock Screen and in the Dynamic Island. links.redirect is the same launch as a plain URL, for an email, an SMS, or a custom button.
The start response includes launch links (iframe embed, redirect, and QR code).
The frame's background is transparent, so the button sits straight on your page and your own colour, gradient or photograph shows through. It never follows the visitor's system setting: add &theme=dark to the iframe's src when you place it on a dark surface, which turns the "Powered By" line under the button white and leaves the button itself untouched. Match the color-scheme in the snippet's style to it (light by default, dark alongside theme=dark): that pairing is what keeps the background transparent whatever colour scheme your own page declares.
Send updates
Target the activityId and send only the fields that change; they are merged into the current state.
1 2 3 4 5 6 7 8 9 10 11 12 13
curl -X POST https://api.webliveactivity.com/api/update \ -H 'Content-Type: application/json' \ -H 'x-api-key: wla_your_key' \ -d '{ "activityId": "act-8f2c1a", "widgetContainerId": "pizza-tracker", "state": { "primaryText": "Out for delivery", "stage": "On the way", "progress": 0.7, "estimatedMinutes": 8 } }'
The Lock Screen and Dynamic Island update in place.
End it
End the activity when the job is done. An optional finalState shows one last state before it dismisses.
1 2 3 4 5 6 7 8 9 10 11 12 13
curl -X POST https://api.webliveactivity.com/api/end \ -H 'Content-Type: application/json' \ -H 'x-api-key: wla_your_key' \ -d '{ "activityId": "act-8f2c1a", "widgetContainerId": "pizza-tracker", "finalState": { "primaryText": "Delivered", "stage": "Delivered", "progress": 1, "isComplete": true } }'
End as soon as the job is done; a lingering activity is a poor experience. Ending keeps the record, so a fresh POST /api/start works any time.
Target a group
A group set on start labels activities. Pass the group alone to update or end every activity in it with one call:
1 2 3 4 5 6 7 8 9 10
curl -X POST https://api.webliveactivity.com/api/update \ -H 'Content-Type: application/json' \ -H 'x-api-key: wla_your_key' \ -d '{ "group": "order-tracker", "widgetContainerId": "pizza-tracker", "state": { "secondaryText": "Kitchen is busier than usual" } }'
Keep long activities alive
iOS dismisses a Live Activity after about eight hours. Set keepAlive: true on start and the service re-invokes it before the limit.
Get lifecycle callbacks
Register a webhook endpoint in the dashboard and the service POSTs to it as each activity goes live, restarts, or ends. Events, signatures, and routing are in the webhooks reference.
Swap the layout on the fly
Send a new layout (and that type's fields) on any update and the activity re-renders as the new type.









