Skip to content

Actions

Add up to 10 buttons that appear when the user long-presses (or pulls down) the notification. Each button can foreground the app, require authentication, or be styled as destructive.

Lock screen notification with image attachment and long-press action menu
PushWard app detail view of the notification with full-size image attachment

The actions array

iOS lets a notification show up to 10 buttons when the user long-presses (or pulls down) the banner. Define them with the actions array — each entry is one button. Labels, icons, and URLs travel with the push, so they can change on every notification.

FieldTypeRequiredDescription
idstringYesStable identifier returned to the app when the user taps. Max 64 chars.
titlestringYesButton label shown to the user. Max 64 chars.
iconstringNoSF Symbol name (iOS 15+), e.g. checkmark.circle, lock.open.
urlstringNoURL opened or dispatched when tapped. Any URL scheme is accepted except javascript:, data:, and file:. Use http(s):// for webhooks (fired silently from inside the app), homeassistant://, shortcuts://, things://, tel:, mailto:, etc. for deep links into other iOS apps, or your own app's custom scheme. Max 2048 chars.
methodstringNoHTTP method for http/https actions: GET (default), POST, PUT, PATCH, DELETE, HEAD. Ignored for custom-scheme URLs.
headersobjectNoMap of header name → value for http/https actions. Example: {"Authorization": "Bearer ..."}. Total ≤ 1 KB. Ignored for custom-scheme URLs.
bodystringNoRequest body for http/https actions. ≤ 1 KB. If set without an explicit Content-Type header, defaults to application/json. Ignored for custom-scheme URLs.
foregroundbooleanNoWhen false (default), tapping fires the URL silently from inside the PushWard iOS app — the user stays on the lock screen, no browser opens. For http/https URLs this is a background URLSession request using the action's method/headers/body; for custom schemes (e.g. homeassistant://) the target app is opened directly. When true, PushWard is brought to the foreground and the URL is opened from the app — only https:// URLs are honored on this path, so use foreground: false for deep links into other apps.
destructivebooleanNoRender the label in red. Use for "Delete", "Deny", "Ignore" style actions.
authentication_requiredbooleanNoRequire Face ID / Touch ID / passcode before firing the action.

Example: Overseerr request approval

A new movie request lands. Three buttons: Approve (silent webhook), Deny (red, silent webhook), and View Details (opens the app). Each id and url is unique to the request.

Overseerr request — approve / deny / view
curl -X POST https://api.pushward.app/notifications \
  -H "Authorization: Bearer hlk_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Overseerr",
    "body": "New request: Dune: Part Two (2024)",
    "source": "overseerr",
    "source_display_name": "Overseerr",
    "actions": [
      {
        "id": "approve",
        "title": "Approve",
        "icon": "checkmark.circle",
        "url": "https://overseerr.example.com/api/v1/request/123/approve"
      },
      {
        "id": "deny",
        "title": "Deny",
        "icon": "xmark.circle",
        "destructive": true,
        "url": "https://overseerr.example.com/api/v1/request/123/decline"
      },
      {
        "id": "view",
        "title": "View Details",
        "icon": "arrow.up.right.square",
        "foreground": true,
        "url": "https://overseerr.example.com/request/123"
      }
    ]
  }'

Example: Home Assistant doorbell

A foreground unlock that requires Face ID, a foreground "view camera," and a destructive "ignore" with no URL.

Doorbell with Unlock / View / Ignore
curl -X POST https://api.pushward.app/notifications \
  -H "Authorization: Bearer hlk_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Front Door",
    "body": "Someone is at the front door",
    "level": "time-sensitive",
    "actions": [
      {
        "id": "unlock",
        "title": "Unlock",
        "icon": "lock.open",
        "foreground": true,
        "authentication_required": true,
        "url": "https://homeassistant.local/unlock"
      },
      {
        "id": "view",
        "title": "View Camera",
        "icon": "video",
        "foreground": true,
        "url": "https://homeassistant.local/camera"
      },
      {
        "id": "ignore",
        "title": "Ignore",
        "icon": "xmark",
        "destructive": true
      }
    ]
  }'

Example: Home Assistant deep link

Skip the browser entirely — tap Open dashboard and the Home Assistant app opens directly to the configured view. Custom-scheme URLs ignore method, headers, and body.

Home Assistant — open the app via deep link
curl -X POST https://api.pushward.app/notifications \
  -H "Authorization: Bearer hlk_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Living room",
    "body": "Motion detected",
    "actions": [
      {
        "id": "open-dashboard",
        "title": "Open dashboard",
        "icon": "house",
        "url": "homeassistant://navigate/lovelace/0"
      }
    ]
  }'

Example: POST to Home Assistant REST API

With method, headers, and body you can call any HTTP endpoint directly — no webhook automation needed. This action calls Home Assistant's REST API to open a cover, with a Bearer token in the Authorization header and a JSON body naming the entity.

Home Assistant — open cover via REST API
curl -X POST https://api.pushward.app/notifications \
  -H "Authorization: Bearer hlk_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Blinds",
    "body": "Open the living room blinds?",
    "actions": [
      {
        "id": "open-blinds",
        "title": "Open",
        "icon": "blinds.horizontal.open",
        "url": "https://homeassistant.local/api/services/cover/open_cover",
        "method": "POST",
        "headers": {
          "Authorization": "Bearer HA_LONG_LIVED_TOKEN"
        },
        "body": "{\"entity_id\":\"cover.blinds_living_room_left\"}"
      }
    ]
  }'