Send 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. Optional tags to organize and filter notification history.
POST https://activitysmith.com/api/push-notificationAuthentication#
Use your API key in the request header.
Authorization: Bearer $YOUR_API_KEYRequest examples#
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",});Bodyapplication/json
metadataMetadatatitlestringrequiredmessagestringsubtitlestringiconstring<uri>- Optional HTTPS image URL without credentials for a custom notification icon. If the image cannot be loaded, the app icon is used. iOS may omit subtitle when displaying a custom icon.
- Pattern:
^https:// interruption_levelPushInterruptionLevelmediastring<uri>- Optional HTTPS URL for an image, audio file, or video that users can preview or play when they expand the notification. If
redirectionis omitted, tapping the notification opens this URL. Cannot be combined withactions. - Pattern:
^https:// redirectionstring<uri>- Optional HTTP, HTTPS, Shortcuts, or installed app URL opened when the user taps the notification body. Custom schemes such as spotify:// and spotify:track:123 require iOS 1.13.4 build 2 or later and an installed handler; no web fallback is provided. Internal and executable schemes are blocked. Overrides the default tap target from media.
- Pattern:
^[A-Za-z][A-Za-z0-9+.-]*:Max Length:2048 actionsarray ofPushNotificationAction- Optional interactive actions shown when users expand the notification. Cannot be combined with
media. - Max Items:
4 payloadobject- Additional Properties:
true badgeintegersoundstringtargetChannelTargettagsTagSlugs
Additional Properties: false
default
{ "title": "New subscription 💸", "message": "Customer upgraded to Pro plan"}channel targeted
{ "title": "New subscription 💸", "message": "Customer upgraded to Pro plan", "target": { "channels": [ "devs", "ops" ] }}redirection
{ "title": "Incident Resolved ✅", "message": "All systems operational", "redirection": "https://status.example.com/incidents/abc-123"}media preview
{ "title": "Homepage ready", "message": "Your agent finished the redesign.", "media": "https://cdn.example.com/output/homepage.png"}media preview with redirection
{ "title": "Homepage ready", "message": "Your agent finished the redesign.", "media": "https://cdn.example.com/output/homepage.png", "redirection": "https://github.com/acme/web/pull/482"}actions open url
{ "title": "Release Candidate Ready 🚀", "message": "v2.14.0-rc.1 deployed to staging", "actions": [ { "title": "View CI Run", "type": "open_url", "url": "https://github.com/activitysmithhq/backend/actions/runs/1234567890" }, { "title": "Release Notes", "type": "open_url", "url": "https://github.com/activitysmithhq/backend/releases/tag/v2.14.0-rc.1" } ]}actions webhook
{ "title": "Build Failed 🚨", "message": "Tap and hold for remediation actions", "redirection": "https://ci.example.com/builds/8842", "actions": [ { "title": "Retry Build", "type": "webhook", "url": "https://hooks.example.com/activitysmith/build-retry", "method": "POST", "body": { "build_id": "8842", "source": "push_action" } } ]}Organize notification history with tags
{ "title": "New subscription 💸", "message": "Customer upgraded to Pro plan", "tags": [ "user:382", "billing" ]}Responses#
200#
Push notification sent
Content type: application/json
Schema: PushNotificationResponse#
successbooleanrequireddevices_notifiedintegerusers_notifiedintegereffective_channel_slugsarray of string or nulltagsTagSlugstimestampstring<date-time>required
Additional Properties: false
default
{ "success": true, "devices_notified": 2, "users_notified": 1, "timestamp": "2025-08-12T12:00:00.000Z"}channel targeted
{ "success": true, "devices_notified": 2, "users_notified": 1, "effective_channel_slugs": [ "devs", "ops" ], "timestamp": "2025-08-12T12:00:00.000Z"}tagged
{ "success": true, "devices_notified": 2, "users_notified": 1, "effective_channel_slugs": null, "tags": [ "user:382", "billing" ], "timestamp": "2025-08-12T12:00:00.000Z"}400#
Bad request (invalid payload or channel targeting input)
Content type: application/json
Schema: BadRequestError#
errorstringrequiredmessagestringrequired
Additional Properties: true
invalid target
{ "error": "Invalid channel targeting", "message": "target.channels must be an array of channel slugs"}invalid tags
{ "error": "Invalid tags", "code": "invalid_tags", "message": "tags must use 1-64 lowercase letters, numbers, dashes, underscores, periods, or colons"}402#
Billing access required
Content type: application/json
Schema: BillingBlockedError#
errorstringrequired- Enum:
["trial_expired","trial_exhausted","billing_overage_cap_reached"] messagestringrequiredtrial_periodobjecttrial_period.started_atstring<date-time>requiredtrial_period.ends_atstring<date-time>requiredupgrade_urlstring<uri>required
Additional Properties: true
403#
Forbidden (API key scope or channel assignment violation)
Content type: application/json
Schema: ForbiddenError#
errorstringrequiredmessagestringrequired
Additional Properties: true
channel scope violation
{ "error": "Invalid channel targeting", "message": "This API key can only target assigned channels. Requested channels include channels outside this key scope."}422#
No recipients found for effective channel target
Content type: application/json
Schema: NoRecipientsError#
errorstringrequiredmessagestringrequiredeffective_channel_slugsarray of string or null
Additional Properties: true
no devices
{ "error": "No recipients found", "message": "No devices matched the effective channel target", "effective_channel_slugs": [ "marketing" ]}429#
Rate limit exceeded
Content type: application/json
oneOf
Schema: RateLimitError
Schema: LiveActivityLimitError
rate limited
{ "error": "Rate limit exceeded", "message": "Too many requests, please try again later."}