Saltar al contenido

API de notificaciones

Envía una notificación a la bandeja de entrada de un usuario, con entrega push opcional por APNs a sus dispositivos.

Create Notification

POST /notifications

Create an in-app notification and optionally push it to all user devices. No subscription required — it counts toward your monthly notification quota (free tier included) and needs the notifications capability, which your default integration key already has.

Request Body

FieldTypeRequiredDescription
titlestringYesNotification title
bodystringYesNotification body text
subtitlestringNoOptional subtitle
levelstringNopassive, active (default), time-sensitive, or critical. Controls iOS interruption level.
volumenumberNoSound volume for critical alerts (0.0–1.0). Only used when level is critical. Defaults to 1.0.
thread_idstringNoGroups notifications in Notification Center
collapse_idstringNoAPNs deduplication key (max 64 chars). Not stored or returned in responses.
sourcestringNoSource identifier (e.g. integration name)
source_display_namestringNoHuman-readable source name shown in notification settings and inbox grouping
urlstringNoAction URL (max 2048 chars, must start with http:// or https://)
mediaobjectNoRich media attachment. url (HTTPS, max 2048 chars) plus type (image, video, or audio). iOS renders inline. Apple size caps: image 10 MB, audio 5 MB, video 50 MB.
actionsarrayNoUp to 10 dynamic action buttons. Each: id (string, max 64), title (string, max 64), optional url, foreground (bool), destructive (bool), authentication_required (bool), icon (SF Symbol name).
icon_urlstringNoPer-notification source avatar, shown as the Communication Notification avatar on iOS. Accepts http or https (max 2048 chars, recommended ≤256×256 and ≤100 KB; the iOS extension rejects responses larger than 512 KB).
metadataobjectNoKey-value string pairs (max 20 keys, key max 64 chars, value max 4096 chars)
activity_slugstringNoOptional link to an existing activity. An unknown slug is rejected with 422 before the notification is persisted.
pushbooleanNoIf true (default), send APNs rich alert to all user devices. Set false to store in the inbox only.
Información

By default, every notification is delivered as an APNs push to the user's devices. Set push: false to store the notification in the inbox without triggering an alert.

Ejemplo
curl -X POST https://api.pushward.app/notifications \
  -H "Authorization: Bearer hlk_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Deploy Complete",
    "body": "Successfully deployed to production",
    "source": "github-actions",
    "source_display_name": "GitHub Actions",
    "level": "active"
  }'

Response (201):

{
  "id": 42,
  "title": "Deploy Complete",
  "subtitle": "",
  "body": "Successfully deployed to production",
  "thread_id": "",
  "level": "active",
  "source": "github-actions",
  "source_display_name": "GitHub Actions",
  "url": "",
  "media_url": "https://example.com/img.png",
  "media_type": "image",
  "actions": [
    { "id": "rerun", "title": "Re-run", "foreground": true }
  ],
  "icon_url": "",
  "metadata": {},
  "activity_slug": "",
  "pushed": true,
  "created_at": "2026-04-24T21:00:00Z",
  "delivery": "all",
  "reason": ""
}

On POST /notifications only, the response also includes two read-only fields describing the APNs fan-out outcome (omitted from GET responses):

FieldValuesMeaning
deliveryall, partial, noneWhether every, some, or no devices accepted the push.
reasonno_apns_token, apns_rejected, push_disabledFailure mode when delivery is not all. Empty on success; omitted entirely when push: false.

Error Responses

Errors follow RFC 9457 Problem Details with Content-Type: application/problem+json. See the canonical Errors section for the body shape and known code values.

StatusMeaning
400Malformed JSON or wrong shape (semantic validation now uses 422)
401Missing or invalid token
403Integration key lacks the notifications capability flag (insufficient permissions)
422Unknown activity_slug, or other semantic validation failure
429Per-IP rate limit (code: rate_limit.exceeded) or monthly notification quota exhausted (code: quota.exceeded) — pairs with Retry-After and retry_after_ms. See Errors for the quota body shape.
500Internal server error