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

# 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} 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}
<?php

declare(strict_types=1);

use ActivitySmith\ActivitySmith;
use ActivitySmith\LiveActivityAction;
use ActivitySmith\LiveActivityAlertBadge;
use ActivitySmith\LiveActivityAlertIcon;
use ActivitySmith\LiveActivityContentState;
use ActivitySmith\LiveActivityMetric;
use ActivitySmith\PushAction;

$apiKey = $_ENV['ACTIVITYSMITH_API_KEY'] ?? 'YOUR-API-KEY';
$activitysmith = new ActivitySmith($apiKey);
```

### 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.

<img className="image" src="https://cdn.activitysmith.com/features/new-subscription-push-notification.png" alt="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

<img className="image image-full-width" src="https://cdn.activitysmith.com/features/rich-push-notification-with-image.png" alt="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.

<img className="image image-full-width" src="https://cdn.activitysmith.com/features/rich-push-notification-with-audio.png" alt="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

<img className="image image-full-width" src="https://cdn.activitysmith.com/features/actionable-push-notifications-2.png" alt="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

<p align="center">
  <img src="https://cdn.activitysmith.com/features/stats-live-activity.png" alt="Stats Live Activity stream example" width="680" />
</p>

```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

<p align="center">
  <img src="https://cdn.activitysmith.com/features/metrics-live-activity-start.png" alt="Metrics Live Activity stream example" width="680" />
</p>

```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

<p align="center">
  <img src="https://cdn.activitysmith.com/features/update-live-activity.png" alt="Segmented Progress Live Activity stream example" width="680" />
</p>

```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

<p align="center">
  <img src="https://cdn.activitysmith.com/features/progress-live-activity.png" alt="Progress Live Activity stream example" width="680" />
</p>

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

#### Alert

<p align="center">
  <img src="https://cdn.activitysmith.com/features/alert-live-activity.png" alt="Alert Live Activity stream example" width="680" />
</p>

```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

<p align="center">
  <img src="https://cdn.activitysmith.com/features/timer-live-activity.png" alt="Timer Live Activity stream example" width="680" />
</p>

```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`.

<p align="center">
  <img src="https://cdn.activitysmith.com/features/metrics-live-activity-with-icon.png" alt="Metrics Live Activity with an SF Symbol icon on the iPhone Lock Screen" width="680" />
</p>

```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.

<p align="center">
  <img src="https://cdn.activitysmith.com/features/progress-live-activity-with-badge.png" alt="Progress Live Activity with a badge on the iPhone Lock Screen" width="680" />
</p>

```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

<p align="center">
  <img src="https://cdn.activitysmith.com/features/metrics-live-activity-action.png" alt="Metrics Live Activity with action" width="680" />
</p>

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

<p align="center">
  <img src="https://cdn.activitysmith.com/features/lock-screen-widgets.png" alt="Lock screen widgets" width="680" />
</p>

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 <a href="https://activitysmith.com/app/widgets" target="_blank" rel="noopener noreferrer">web app</a>, then update the metric value using our API, add a widget to your lock screen and it will fetch the latest update automatically.

<p align="center">
  <img src="https://cdn.activitysmith.com/features/create-widget-metric.png" alt="Create widget metric" width="680" />
</p>

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

<CardGroup cols={2}>
  <Card title="Packagist" icon="php" href="https://packagist.org/packages/activitysmith/activitysmith">
    Install the ActivitySmith PHP SDK from Packagist
  </Card>

  <Card title="Source Code" icon="github" href="https://github.com/ActivitySmithHQ/activitysmith-php">
    View the PHP SDK source on GitHub
  </Card>
</CardGroup>
