Chuyển đến nội dung

Kiểu giao tiếp

Đặt icon_url để hiển thị thông báo theo kiểu Communication Notification của iOS — một ảnh đại diện tròn ở bên cạnh, giống như iMessage. Kết hợp với thread_id để nhóm trong Notification Center.

Notification rendered in iOS Communication style with a source avatar
PushWard app detail view of the Communication-style notification with sender avatar

Source identity

FieldTypeDescription
sourcestringStable internal id — e.g. sonarr, github-actions, home-assistant. Used for filtering and analytics.
source_display_namestringThe pretty version users see — e.g. Sonarr, GitHub Actions. Shown above the title and used to group notifications under that source in iOS settings and the inbox.
icon_urlstringHTTPS avatar (max 2048 chars). Recommended ≤256×256 and ≤100 KB; the iOS extension rejects responses larger than 512 KB to protect its 24 MB memory budget. When set, iOS renders the notification in Communication Notification style — a round avatar floating on the side, like an iMessage.
Thông tin

Communication Notifications were introduced in iOS 15 for messaging apps. PushWard uses the same APIs to give your push notifications a personality — the source avatar floats on the side instead of being embedded as a tiny attachment.

Example: Home Assistant doorbell

Thông báo kiểu giao tiếp
curl -X POST https://api.pushward.app/notifications \
  -H "Authorization: Bearer hlk_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Front Door",
    "subtitle": "Doorbell pressed · 13:45",
    "body": "Someone is at the front door",
    "level": "time-sensitive",
    "source": "home-assistant",
    "source_display_name": "Home Assistant",
    "thread_id": "ha-doorbell",
    "icon_url": "https://www.home-assistant.io/images/favicon-192x192.png",
    "push": true
  }'

Threading with thread_id

When several notifications belong to the same "conversation," give them all the same thread_id. iOS stacks them as one expandable group in Notification Center — the user sees a single row that opens to reveal the full list. They add up; nothing is overwritten.

Good real-world threads:

  • Every download for one show: thread_id: "sonarr-the-bear"
  • Every message in one chat: thread_id: "chat-42"
  • Every alert from one host: thread_id: "alerts-prod-db-01"
Two Sonarr downloads stack as one group
# First episode
curl -X POST https://api.pushward.app/notifications \
  -H "Authorization: Bearer hlk_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Sonarr",
    "body": "The Bear S03E01 downloaded",
    "thread_id": "sonarr-the-bear",
    "source": "sonarr",
    "source_display_name": "Sonarr",
    "push": true
  }'

# Second episode — appears stacked under the first
curl -X POST https://api.pushward.app/notifications \
  -H "Authorization: Bearer hlk_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Sonarr",
    "body": "The Bear S03E02 downloaded",
    "thread_id": "sonarr-the-bear",
    "source": "sonarr",
    "source_display_name": "Sonarr",
    "push": true
  }'

Replacement with collapse_id

When you only care about the latest value of something, send each update with the same collapse_id. APNs replaces the previous notification on-device — the user always sees one row, and it keeps changing.

Good real-world collapses:

  • CI build progress: collapse_id: "build-482" with body cycling through "running 12%" → "running 84%" → "passed".
  • Live score updates: collapse_id: "match-arsenal-chelsea".
  • Battery / charge percent on a 3D print: collapse_id: "printer-x1c".
Thông tin

collapse_id is a pure APNs delivery hint — PushWard does not store it, and it's not returned in the response. Keep it under 64 characters.

Build status that updates in place
# Build kicks off
curl -X POST https://api.pushward.app/notifications \
  -H "Authorization: Bearer hlk_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Build #482",
    "body": "Status: running (12%)",
    "collapse_id": "build-482",
    "source": "github-actions",
    "source_display_name": "GitHub Actions",
    "push": true
  }'

# Final status — overwrites the previous notification on-device
curl -X POST https://api.pushward.app/notifications \
  -H "Authorization: Bearer hlk_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Build #482",
    "body": "Status: passed (100%)",
    "collapse_id": "build-482",
    "source": "github-actions",
    "source_display_name": "GitHub Actions",
    "push": true
  }'

Combine the two

Use thread_id and collapse_id together to get the best of both: every build groups under one stack in Notification Center, while each individual build only ever shows its latest status.

Group all builds, but keep one row per build
{
  "title": "Build #482",
  "body": "Status: passed (100%)",
  "thread_id": "ci-builds",
  "collapse_id": "build-482",
  "source": "github-actions",
  "source_display_name": "GitHub Actions",
  "push": true
}