Push Notifications EndpointsView Markdown ↗

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

Authentication#

Use your API key in the request header.

Authorization: Bearer $YOUR_API_KEY

Request 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

metadataMetadata
titlestringrequired
messagestring
subtitlestring
iconstring<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_levelPushInterruptionLevel
mediastring<uri>
Optional HTTPS URL for an image, audio file, or video that users can preview or play when they expand the notification. If redirection is omitted, tapping the notification opens this URL. Cannot be combined with actions.
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 of PushNotificationAction
Optional interactive actions shown when users expand the notification. Cannot be combined with media.
Max Items: 4
payloadobject
Additional Properties: true
badgeinteger
soundstring
targetChannelTarget
tagsTagSlugs

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#

successbooleanrequired
devices_notifiedinteger
users_notifiedinteger
effective_channel_slugsarray of string or null
tagsTagSlugs
timestampstring<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#

errorstringrequired
messagestringrequired

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"]
messagestringrequired
trial_periodobject
trial_period.started_atstring<date-time>required
trial_period.ends_atstring<date-time>required
upgrade_urlstring<uri>required

Additional Properties: true

403#

Forbidden (API key scope or channel assignment violation)

Content type: application/json

Schema: ForbiddenError#

errorstringrequired
messagestringrequired

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#

errorstringrequired
messagestringrequired
effective_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."
}

Download the OpenAPI specification