Notifications
One-shot push notification attempts to eligible registered devices. No persistent card or lifecycle—just a title, body, and supported rich fields. The current response reports provider acceptance; it does not expose proof that iOS displayed the banner.
Quick start
The raw HTTP path is for reviewed headless integrations. Inject $CHIRP_API_KEY from a secret manager; never paste its value into a prompt, URL, source file, or shared command. Interactive agent hosts should pair with chirp login. Review the headless credential launch gate in the dashboard.
curl -X POST https://api.chirpapp.dev/v1/notify \
-H "Authorization: Bearer $CHIRP_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"Hello from Chirp","body":"Your first notification!"}'Inspect the JSON response for API/provider acceptance. The current notification route has no handset-display acknowledgement, so a 2xx response—and even an upstream provider receipt—must not be described as proof that iOS displayed the banner. The guided onboarding demo has a separate Live Activity device acknowledgement.
Reviewed SDK/connector sources may wrap this endpoint. See the integrations page for source examples and explicit release status.
Notifications vs Live Activities
Notification
- Fire-and-forget — no lifecycle to manage
- Supports sounds, subtitles, tap-to-open URLs
- Groups via thread_id in Notification Center
- Best for: alerts, one-time events, status updates
Live Activity
- Persistent card on the lock screen and Dynamic Island
- Start → update → end lifecycle
- Rich template layouts (@deploy, @agent, @training, etc.)
- Best for: long-running tasks, builds, training runs, monitoring
Schema reference
POST to /v1/notify with a JSON body containing any of these fields.
titlerequiredFirst line of the notification. Max 200 characters.
bodyrequiredPrimary content of the notification. Max 4000 characters.
subtitleLine displayed below the title in smaller text. Useful for source or category labels.
soundUse "default" for the standard iOS notification sound, or the name of a custom sound bundled in the app (e.g. "chirp"). Omit to use the default sound.
image_urlReserved for a future Chirp-owned image proxy. The launch API rejects any request containing this field with HTTP 400; omit it rather than expecting a text-only fallback.
open_urlURL to open when the user taps the notification. External URLs open in the browser; deep links (chirp://) route inside the app.
thread_idGroups related notifications together in Notification Center. Use consistent thread IDs to bundle notifications (e.g. all deploy alerts under "deploys").
interruption_levelControls how urgently the notification is delivered. Options: "passive" (silent, no screen wake), "active" (default — sound + screen), "time-sensitive" (breaks through Focus and Notification Summary), "critical" (overrides mute, requires Apple entitlement).
volumeSound volume for critical alerts only. Only applies when interruption_level is "critical". Defaults to full volume (1).
filter_criteriaMatches a Focus filter configured on the device. If the active Focus allows this criterion, the notification can be shown.
dataBounded key-value data passed to app handlers. Do not include prompts, source, credentials, personal data, or unredacted command output.
priorityDelivery priority hint. "high" (default for notifications), "normal", or "default". High-priority notifications wake the device; normal may be batched.
Examples
Minimal notification
curl -X POST https://api.chirpapp.dev/v1/notify \
-H "Authorization: Bearer $CHIRP_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"Deploy complete","body":"my-app v2.4.1 is live"}'Notification with subtitle and tap URL
curl -X POST https://api.chirpapp.dev/v1/notify \
-H "Authorization: Bearer $CHIRP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "New order",
"body": "$129.99 from sarah@example.com",
"subtitle": "Shopify",
"sound": "default",
"open_url": "https://admin.shopify.com/orders/12345",
"thread_id": "orders"
}'Time-sensitive alert
Breaks through Focus and Notification Summary on the user’s device.
curl -X POST https://api.chirpapp.dev/v1/notify \
-H "Authorization: Bearer $CHIRP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Server down",
"body": "api-prod-3 is unreachable. Last ping 45s ago.",
"sound": "default",
"interruption_level": "time-sensitive"
}'Python SDK · preview package
import chirp
chirp.notify(
title="Build complete",
body="my-app v2.4.1 deployed to production",
sound="default",
thread_id="deploys",
)
# With all options:
chirp.notify(
title="Payment received",
body="$49.99 from customer@example.com",
subtitle="Stripe",
sound="chirp",
open_url="https://dashboard.stripe.com/payments/pi_123",
interruption_level="active",
)Node SDK · preview package
// Source preview: @chirp/sdk is not published yet.
import { ChirpClient } from "@chirp/sdk";
const chirp = new ChirpClient();
await chirp.notify("Build complete", "my-app v2.4.1 deployed to production", {
sound: "default",
thread_id: "deploys",
});Bash helper
# Reviewed local connectors/bash/chirp.sh copy
source ~/.chirp.sh
chirp_notify "Deploy done" "my-app is live"Sounds
The sound field controls what plays when the notification arrives.
"default"Standard iOS notification sound."chirp"Custom Chirp notification sound (bundled in the app).- omittedDefault notification sound.
Interruption levels
iOS lets you control how urgently a notification is presented. Set the interruption_level field to one of these values.
passiveSilently added to Notification Center. No sound, no screen wake, no banner. Use for low-priority informational updates.
activeDefault behavior. Presents a banner, lights up the screen, plays the sound. This is what you get when you omit the field entirely.
time-sensitiveRequests time-sensitive presentation. Actual behavior still depends on app entitlement, user authorization, Focus settings, and iOS policy.
criticalRequests critical presentation and volume. It works only when the signed app has Apple's critical-alert entitlement and the user granted permission; do not depend on it until that production entitlement is verified.
Remote image attachments
Remote image_url attachments are disabled in the launch build. The API rejects a request containing that field with HTTP 400, so callers must omit it; Chirp does not silently send a text-only variant. The app does not fetch a push-controlled URL from the device.
- Planned: server-side validation, size/type caps, and rewrite to an immutable Chirp-owned CDN URL
- Live Activity backgrounds are finite procedural SwiftUI presets compiled into the app; they do not load remote images
- Do not depend on remote notification artwork until the docs mark the Chirp-owned proxy as available
Thread grouping
Set thread_id to group related notifications in Notification Center. All notifications with the same thread ID are bundled together — the user sees a stack instead of individual items.
Good thread IDs are stable, meaningful strings like deploys, orders, ci-main, or alerts-prod.
Tap-to-open URLs
Set open_url to open a link when the user taps the notification. External URLs (https://) open in the browser. The app’s internal deep links (chirp://) route to the appropriate screen.
Send notifications from…
Use the Notification toggle on each integration page to see the notification-specific setup.