GET/v1/notifications

List of sends (notifications:read)

Key: sk_

Parameters

NameInTypeDescription
appIdquerystring
statusquerystring
sourcequery"api" | "panel" | "campaign" | "recurring"
pagequeryinteger
perPagequeryinteger

Responses: 200

curl -X GET "https://api.pushtifly.com/v1/notifications" \
  -H "Authorization: Bearer sk_test_YOUR_SECRET_KEY"

POST/v1/notifications

Create a send (sk_ with notifications:send). It is queued and responds 202.

Key: sk_

Targets: devices {ids|tokens}, external_users {ids}, topic {name}, all, test_devices. With a test-mode key
the send only reaches test devices. segment/filters, media and schedule other than now arrive in Phase 4.
validateOnly=true validates and estimates without creating. Errors: 2001/2002 validation, 2003 payload > 4 KB, 2004 platform,
2011 scheduling, 4005 Idempotency-Key reused with a different body. 2002 with errors.content = [blocked]: the
content links to a domain or URL blocked by the platform.

Parameters

NameInTypeDescription
Idempotency-KeyheaderstringRepeating the same key (24 h) returns the original notification without duplicating it

Body

FieldTypeDescription
contentType"alert" | "data_only" | "silent"
contentobjectPer language, e.g. { en: { title, subtitle, body } }
variablesobjectThey replace {{name}} in the text
dataobject
deepLinkstringmax. 500 characters
badgeinteger
soundstringdefault or a sound registered in the app (2002 if it doesn't exist)
ttlSecondsinteger0–2419200
priority"high" | "normal"
androidobject
android.channelIdstring
android.collapseKeystring
android.colorstring
android.tagstring
android.iconstring
iosobject
ios.interruptionLevel"passive" | "active" | "time-sensitive" | "critical"
ios.threadIdstring
ios.collapseIdstring
ios.relevanceScorenumber
ios.mutableContentboolean
appIdstring
target*object
target.type*"devices" | "external_users" | "topic" | "segment" | "filters" | "all" | "test_devices"
target.segmentIdstring
target.rulesobjectAND/OR tree (maximum 3 levels, 20 conditions). Fields: platform, language, country, timezone, external_user_id, app_version, last_seen, tag (with key), topic, notifications_enabled, capability.
target.idsstring[]
target.tokensstring[]
target.namestring
platforms"android" | "ios" | "web"[]
category"transactional" | "marketing"
scheduleobjectnow; at {sendAt, timezone}: fixed time (no offset = in timezone; defaults to the company's); local_time {date, time}: that time in each device's zone (~26 h). Maximum 365 days. Errors 2011 / 2012.
schedule.type"now" | "at" | "local_time"
schedule.sendAtstring
schedule.timezonestring
schedule.datestring
schedule.timestring
schedule.windowMinutesintegerGradual delivery · 0–1440
schedule.expireAtstringDon't send after this (also caps the TTL)
validateOnlyboolean
templateIdstringTemplate: what you send in the request takes priority; its variables are required (2001)
mediaobjectOnly the URL travels in the payload. Android: large image (or GIF/video poster); iOS: mutable-content + _ph.media for the extension. A file still processing is only accepted in scheduled sends (4009 if immediate). Carousel: type carousel with items (2 to 5 images); without an SDK that draws it, the first one is shown.
media.type"image" | "gif" | "audio" | "video" | "carousel"
media.mediaIdstring
media.urlstringExternal https (requires type)
media.fallback"poster" | "none"
media.itemsobject[]Only with type carousel: 2 to 5 images (mediaId or https url), with optional title (text or per language, up to 40 characters) and link · max. 5 items
largeIconobjectImage (Android, via SDK)
largeIcon.mediaIdstring
largeIcon.urlstring
actionsobject[]max. 3 items

Responses: 200202422

curl -X POST "https://api.pushtifly.com/v1/notifications" \
  -H "Authorization: Bearer sk_test_YOUR_SECRET_KEY" \
  -H "Idempotency-Key: order-123" \
  -H "Content-Type: application/json" \
  -d '{
  "appId": "YOUR_APP_ID",
  "target": {
    "type": "external_users",
    "ids": [
      "customer-123"
    ]
  },
  "content": {
    "en": {
      "title": "Your order is on its way",
      "body": "Arriving today between 2 and 4 p.m."
    },
    "es": {
      "title": "Tu pedido va en camino",
      "body": "Llega hoy entre 2 y 4 p. m."
    }
  },
  "data": {
    "orderId": "A-1029"
  },
  "deepLink": "myapp://orders/A-1029",
  "category": "transactional"
}'

POST/v1/notifications/test

Synchronous test console (up to 10 targets; doesn't use quota; daily limit 3006)

Key: sk_

Returns per target result, interpretation and suggestion (in Spanish), provider_response (HTTP status, code, body, latency) and the request without the full token. Mode validate_only only for FCM.

Body

FieldTypeDescription
contentType"alert" | "data_only" | "silent"
contentobjectPer language, e.g. { en: { title, subtitle, body } }
variablesobjectThey replace {{name}} in the text
dataobject
deepLinkstringmax. 500 characters
badgeinteger
soundstring
ttlSecondsinteger0–2419200
priority"high" | "normal"
androidobject
android.channelIdstring
android.collapseKeystring
android.colorstring
android.tagstring
android.iconstring
iosobject
ios.interruptionLevel"passive" | "active" | "time-sensitive" | "critical"
ios.threadIdstring
ios.collapseIdstring
ios.relevanceScorenumber
ios.mutableContentboolean
appIdstring
useTestDevicesboolean
targetsobject[]max. 10 items
mode"send" | "validate_only"
environment"auto" | "sandbox" | "production"
rawPayloadobjectFinal hand-written payload that replaces the generated one: fcm = FCM v1 message (without token), apns = APNs body (must include aps). Pushtifly adds the token and the APNs headers. Maximum 4 KB; error 2002 if it isn't valid.
rawPayload.fcmobject
rawPayload.apnsobject

Responses: 200429

curl -X POST "https://api.pushtifly.com/v1/notifications/test" \
  -H "Authorization: Bearer sk_test_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "appId": "YOUR_APP_ID",
  "targets": [
    {
      "token": "DEVICE_TOKEN"
    }
  ],
  "content": {
    "en": {
      "title": "Test",
      "body": "Hello from the test console"
    }
  },
  "mode": "send"
}'

GET/v1/notifications/{id}

Status and counters of a send

Key: sk_

Parameters

NameInTypeDescription
id*pathstring

Responses: 200404

curl -X GET "https://api.pushtifly.com/v1/notifications/ID_ID" \
  -H "Authorization: Bearer sk_test_YOUR_SECRET_KEY"

PATCH/v1/notifications/{id}

Edit a scheduled send: full body, or only {schedule} to reschedule (4009 if it already went out)

Key: sk_

Parameters

NameInTypeDescription
id*pathstring

Responses: 200

curl -X PATCH "https://api.pushtifly.com/v1/notifications/ID_ID" \
  -H "Authorization: Bearer sk_test_YOUR_SECRET_KEY"

GET/v1/notifications/{id}/deliveries

Deliveries per device

Key: sk_

Parameters

NameInTypeDescription
id*pathstring
statusquery"queued" | "accepted" | "failed" | "invalid_token" | "expired" | "skipped"
pagequeryinteger
perPagequeryinteger

Responses: 200

curl -X GET "https://api.pushtifly.com/v1/notifications/ID_ID/deliveries" \
  -H "Authorization: Bearer sk_test_YOUR_SECRET_KEY"

POST/v1/notifications/{id}/cancel

Cancel (only while still queued; otherwise 4004)

Key: sk_

Parameters

NameInTypeDescription
id*pathstring

Responses: 200409

curl -X POST "https://api.pushtifly.com/v1/notifications/ID_ID/cancel" \
  -H "Authorization: Bearer sk_test_YOUR_SECRET_KEY"

POST/v1/notifications/{id}/send-now

Send a scheduled notification now (4009 if it isn't scheduled)

Key: sk_

Parameters

NameInTypeDescription
id*pathstring

Responses: 200

curl -X POST "https://api.pushtifly.com/v1/notifications/ID_ID/send-now" \
  -H "Authorization: Bearer sk_test_YOUR_SECRET_KEY"

GET/v1/templates

App templates (send with templateId + variables; notifications:read)

Key: sk_

Parameters

NameInTypeDescription
appIdquerystring

Responses: 200

curl -X GET "https://api.pushtifly.com/v1/templates" \
  -H "Authorization: Bearer sk_test_YOUR_SECRET_KEY"