Skip to main content

/i/push/message/create

Overview

Create a new push notification campaign. Supports various trigger types (schedule, event-based, cohort-based, API-triggered), audience targeting with filters, multi-platform delivery, and content personalization. Messages can be created as drafts for later activation or as active campaigns for immediate scheduling.

Related Endpoints:


Endpoint

/i/push/message/create

Authentication

  • Required Permission: Create access to push feature (create-permission validation)
  • HTTP Methods: POST recommended (GET supported but not practical due to payload size)
  • Content-Type: application/x-www-form-urlencoded or JSON

Request Parameters

ParameterTypeRequiredDescription
api_keyStringYesAPI authentication key
app_idStringYesApplication ID (alias for app)
appObjectIDYesApplication ID (MongoDB ObjectID)
platformsString[]YesPlatforms to send to: ["i", "a", "w", "h"] (iOS, Android, Web, Huawei)
statusStringNoSet to "draft" to create draft (editable), omit for active campaign
save ResultsBooleanNoStore individual push results for debugging (default: false)
filterObjectNoAudience targeting filter (empty = all users with tokens)
filter.userJSON StringNoMongoDB query for app_users{APP_ID} collection
filter.drillJSON StringNoDrill plugin filter (requires Drill plugin)
filter.geosObjectID[]NoArray of geo location IDs
filter.cohortsString[]NoArray of cohort IDs
triggersObject[]YesArray of trigger definitions (min: 1)
triggers[].kindStringYesTrigger type: "plain", "event", "cohort", "api", "recurring"
triggers[].startDateYesCampaign start date (epoch ms or ISO string)
triggers[].endDateNoCampaign end date (for event/cohort/api triggers)
triggers[].sctzNumberNo[plain only] Timezone offset in minutes for user-timezone sending
triggers[].delayedBooleanNo[plain only] Delay audience selection to 5 min prior to start
triggers[].timeNumberNo[event/cohort] Time in ms since 00:00 for user-timezone sending
triggers[].delayNumberNo[event/cohort] Delay in ms after event/cohort change
triggers[].rescheduleBooleanNo[event/cohort] Allow rescheduling to next day if too late
triggers[].capNumberNo[event/cohort/api] Max notifications per user
triggers[].sleepNumberNo[event/cohort/api] Min ms between notifications per user
triggers[].eventsString[]No[event only] Event keys to trigger on
triggers[].cohortsString[]No[cohort only] Cohort IDs to trigger on
triggers[].entryBooleanNo[cohort only] Trigger on entry (true) or exit (false)
triggers[].cancelsBooleanNo[cohort only] Cancel if user exits cohort before send
contentsObject[]YesArray of content objects (min: 1)
contents[0]ObjectYesDefault content (no p or la keys)
contents[].pStringNoPlatform this content applies to: i, a, w, h
contents[].laStringNoLanguage code (2-letter ISO: en, tr, etc.)
contents[].messageStringYesNotification message text
contents[].messagePersObjectNoMessage personalization map (index → personalization object)
contents[].titleStringNoNotification title
contents[].titlePersObjectNoTitle personalization map
contents[].soundStringNoNotification sound
contents[].badgeNumberNoNotification badge number
contents[].dataJSON StringNoCustom data payload
contents[].extrasString[]NoUser property keys to include
contents[].urlStringNoOn-tap URL
contents[].mediaStringNoMedia attachment URL
contents[].mediaMimeStringNoMedia MIME type
contents[].buttonsObject[]NoAction buttons array
contents[].buttons[].titleStringYesButton title
contents[].buttons[].urlStringNoButton URL
contents[].specificObjectNoPlatform-specific options (subtitle for iOS, large_icon for Android)
info.titleStringNoCampaign title for UI (internal name)
demoBooleanNoMark as demo message (for testing/populator)

Filter Structure

The filter object defines the target audience for the push notification:

{
"user": {
"and": [
{"sg.app_version": {"$in": ["2.0", "2.1"]}},
{"sg.country": {"$eq": "US"}},
{"up.premium": {"$eq": true}}
]
},
"drill": {
"queryObject": {
"chr.platform": {"$in": ["Android", "iOS"]}
}
},
"geos": ["507f1f77bcf86cd799439011"],
"cohorts": ["cohort_id_1"]
}

Filter Fields:

  • user: MongoDB query on app_users collection — filters on user properties, segments, and push tokens
  • drill: Drill plugin filter on events/sessions data (requires Drill plugin)
  • geos: Array of geo-fence ObjectIDs for location-based targeting
  • cohorts: Array of cohort IDs for behavioral targeting

If filter is omitted or empty, the campaign targets all users with valid push tokens.

Contents Structure

The contents array defines the notification content, with support for platform and language overrides:

[
{
"message": "Your order has been shipped!",
"title": "Order Update",
"sound": "default",
"badge": 1,
"url": "https://example.com/orders",
"media": "https://example.com/img/shipped.png",
"mediaMime": "image/png",
"data": "{\"orderId\": \"12345\"}",
"buttons": [
{"title": "View Order", "url": "https://example.com/orders/12345"}
]
},
{
"p": "i",
"message": "iOS-specific message",
"specific": {"subtitle": "Order #12345"}
},
{
"la": "es",
"message": "¡Tu pedido ha sido enviado!",
"title": "Actualización de pedido"
}
]
  • The first object (no p or la keys) is the default content — required.
  • Objects with p override content for a specific platform (i, a, w, h).
  • Objects with la override content for a specific language (2-letter ISO code).
  • Platform and language overrides are merged with the default; only specified fields are replaced.

Response

Success Response - Campaign Created

Status Code: 200 OK

Body: Complete message object with generated _id and metadata

Success Response

{
"_id": "507f1f77bcf86cd799439011",
"app": "507f1f77bcf86cd799439012",
"platforms": ["i", "a"],
"status": "scheduled",
"state": 1,
"saveResults": false,
"filter": {
"user": "{\"country\":\"US\"}",
"drill": null,
"geos": [],
"cohorts": []
},
"triggers": [{
"kind": "plain",
"start": "2024-12-31T18:00:00.000Z",
"sctz": -180,
"delayed": false
}],
"contents": [{
"message": "Happy New Year!",
"title": "Celebration",
"sound": "default",
"badge": 1,
"url": "https://example.com/newyear"
}],
"result": {
"total": 0,
"processed": 0,
"sent": 0,
"actioned": 0,
"failed": 0,
"lastErrors": [],
"lastRuns": []
},
"info": {
"title": "New Year Campaign",
"appName": "My App",
"created": "2024-12-15T10:30:00.000Z",
"createdBy": "507f191e810c19729de860ea",
"createdByName": "John Doe",
"updated": "2024-12-15T10:30:00.000Z",
"updatedBy": "507f191e810c19729de860ea",
"updatedByName": "John Doe"
}
}

Error Response - Validation Error

Status Code: 400 Bad Request

Body:

{
"kind": "ValidationError",
"errors": [
"platforms is required",
"triggers is required",
"contents is required"
]
}

Error Response - No Credentials

Status Code: 400 Bad Request

Body:

{
"kind": "ValidationError",
"errors": [
"No push credentials for iOS platform"
]
}

Response Fields

FieldTypeDescription
(root)ObjectFull created message object returned by push message model.
_idStringCreated message ID.
statusStringInitial runtime status after creation.
triggersArrayTrigger definitions stored for the message.
contentsArrayPush content blocks stored for the message.
resultObjectRuntime counters and tracking fields.

Error Responses

{
"result": "Error"
}

Permissions

  • Required Permission: Create access to push feature (create-permission validation)

Behavior/Processing

Operation Flow

  1. Validation

    • Validates all required fields and data types
    • For drafts: Relaxed validation (allows incomplete data)
    • For active: Full validation including credentials check
  2. Credentials Verification

    • Checks apps.features.push.{platform}._id exists for each platform
    • Queries push_{credentials_id} collection to verify credentials exist
    • Rejects if credentials missing or set to 'demo'
  3. Filter Validation

    • If filter.geos provided: Verifies geo IDs exist in geos collection
    • If filter.cohorts provided: Verifies cohort IDs exist in cohorts collection
  4. Message Creation

    • Generates new ObjectID for _id
    • Sets info.created, info.updated timestamps
    • Sets info.createdBy, info.createdByName from member
    • If demo: Sets info.demo = true
  5. Status Handling

    • Draft: Sets status = "draft", saves immediately, dispatches push_message_draft log
    • Active: Sets status = "active", checks Push Approver feature, schedules if eligible
  6. Push Approver Integration (if feature enabled)

    • Calls push_approver.onMessageActivated()
    • May change status to "inactive" (pending approval)
  7. Scheduling

    • Calls scheduleIfEligible() to queue message for sending
    • For plain triggers: Schedules based on start date
    • For event/cohort/api triggers: Sets up event listeners
  8. System Logging

    • Dispatches /systemlogs event with action push_message_created
    • Includes full message JSON in audit trail
  9. Demo Data (if demo parameter set)

    • Generates synthetic engagement data for testing/demos
    • Does not affect actual message sending
  10. Response

    • Returns complete message object with all generated fields

Draft vs Active

Draft Mode (status: "draft"):

  • Relaxed validation (can save incomplete data)
  • Not scheduled for sending
  • Editable without restrictions
  • Useful for gradual campaign building in UI

Active Mode (status omitted or status: "active"):

  • Full validation required
  • Immediately scheduled (if trigger date is future)
  • Requires push credentials configured
  • May require approval if Push Approver feature enabled

Trigger Type Details

Plain Trigger (Scheduled):

{
"kind": "plain",
"start": "2024-12-31T18:00:00.000Z",
"sctz": -180,
"delayed": false
}
  • Sends at specific date/time
  • sctz: Timezone offset for user-timezone sending (e.g., -180 for GMT+3)
  • delayed: Delay audience selection to 5 min before send (for dynamic segments)

Event Trigger:

{
"kind": "event",
"start": "2024-01-01T00:00:00.000Z",
"end": "2024-12-31T23:59:59.000Z",
"events": ["purchase", "level_complete"],
"delay": 3600000,
"cap": 5,
"sleep": 86400000
}
  • Sends when users perform specified events
  • delay: Wait time after event (ms)
  • cap: Max notifications per user during campaign
  • sleep: Min time between notifications (ms)

Cohort Trigger:

{
"kind": "cohort",
"start": "2024-01-01T00:00:00.000Z",
"end": "2024-12-31T23:59:59.000Z",
"cohorts": ["premium_users"],
"entry": true,
"cancels": true,
"time": 36000000
}
  • Sends when users enter/exit cohorts
  • entry: true = send on join, false = send on leave
  • cancels: Cancel notification if user exits cohort before send
  • time: Time of day to send (ms since 00:00 in user timezone)

Content Structure

Content objects are layered with inheritance:

  1. First content (index 0) has no p or la - serves as default
  2. Subsequent contents with p override default for specific platform
  3. Contents with la override for specific language
  4. Contents with both p and la override for platform+language combo

Example:

{
"contents": [
{
"message": "Default message",
"title": "Default title"
},
{
"p": "i",
"message": "iOS-specific message"
},
{
"la": "tr",
"message": "Turkish message"
},
{
"p": "i",
"la": "tr",
"message": "Turkish message for iOS"
}
]
}

Personalization

Personalization objects map string indexes to replacement definitions:

{
"messagePers": {
"0": {
"k": "first_name",
"t": "c",
"c": true,
"f": "User"
}
}
}
  • Index "0": Replace from character 0 in message
  • k: Property key (first_name)
  • t: Type - "u" (user prop), "c" (custom prop), "e" (event data), "a" (API variable)
  • c: Capitalize (true/false)
  • f: Fallback value if property missing

Message: " {first_name}, check this out!""John, check this out!"


Examples

Example 1: Simple scheduled notification

Description: Send "Happy New Year!" to all iOS users on Dec 31, 2024 at 6 PM GMT+3

Request (POST):

curl -X POST "https://your-server.com/i/push/message/create" \
-H "Content-Type: application/json" \
-d '{
"api_key": "YOUR_API_KEY",
"app": "507f1f77bcf86cd799439012",
"platforms": ["i"],
"triggers": [{
"kind": "plain",
"start": "2024-12-31T18:00:00.000Z",
"sctz": -180
}],
"contents": [{
"message": "Happy New Year! 🎉",
"title": "Celebration",
"sound": "default",
"badge": 1
}],
"info": {
"title": "New Year Campaign"
}
}'

Response (200):

{
"_id": "507f1f77bcf86cd799439011",
"app": "507f1f77bcf86cd799439012",
"platforms": ["i"],
"status": "scheduled",
"triggers": [{
"kind": "plain",
"start": "2024-12-31T18:00:00.000Z",
"sctz": -180
}],
"contents": [{
"message": "Happy New Year! 🎉",
"title": "Celebration",
"sound": "default",
"badge": 1
}],
"info": {
"title": "New Year Campaign",
"created": "2024-12-15T10:30:00.000Z",
"createdBy": "507f191e810c19729de860ea"
}
}

Example 2: Event-triggered notification with personalization

Description: Send personalized notification when users complete level 10

Request (POST):

curl -X POST "https://your-server.com/i/push/message/create" \
-H "Content-Type: application/json" \
-d '{
"api_key": "YOUR_API_KEY",
"app": "507f1f77bcf86cd799439012",
"platforms": ["i", "a"],
"triggers": [{
"kind": "event",
"start": "2024-01-01T00:00:00.000Z",
"end": "2024-12-31T23:59:59.000Z",
"events": ["level_complete"],
"delay": 300000,
"cap": 1
}],
"contents": [{
"message": " {first_name}, congrats on level 10!",
"messagePers": {
"0": {
"k": "first_name",
"t": "c",
"c": true,
"f": "Player"
}
},
"title": "Achievement Unlocked!",
"media": "https://cdn.example.com/level10.png",
"mediaMime": "image/png",
"url": "myapp://rewards"
}],
"filter": {
"user": "{\\"custom.level\\": 10}"
}
}'

Example 3: Draft notification

Description: Create draft for later editing

Request (POST):

curl -X POST "https://your-server.com/i/push/message/create" \
-H "Content-Type: application/json" \
-d '{
"api_key": "YOUR_API_KEY",
"app": "507f1f77bcf86cd799439012",
"platforms": ["a"],
"status": "draft",
"triggers": [{
"kind": "plain",
"start": "2024-12-01T10:00:00.000Z"
}],
"contents": [{
"message": "Draft message",
"title": "Draft"
}]
}'

Response (200):

{
"_id": "507f1f77bcf86cd799439013",
"status": "draft",
"app": "507f1f77bcf86cd799439012"
}

Example 4: Multi-language, multi-platform notification

Description: Campaign with content variants for iOS/Android and English/Turkish

Request (POST):

curl -X POST "https://your-server.com/i/push/message/create" \
-H "Content-Type: application/json" \
-d '{
"api_key": "YOUR_API_KEY",
"app": "507f1f77bcf86cd799439012",
"platforms": ["i", "a"],
"triggers": [{
"kind": "plain",
"start": "2024-12-25T12:00:00.000Z"
}],
"contents": [
{
"message": "Merry Christmas!",
"title": "Happy Holidays"
},
{
"p": "i",
"message": "Merry Christmas!",
"title": "🎄 Happy Holidays",
"specific": {
"subtitle": "Special iOS subtitle"
}
},
{
"p": "a",
"message": "Merry Christmas!",
"specific": {
"large_icon": "https://cdn.example.com/christmas_icon.png"
}
},
{
"la": "tr",
"message": "Mutlu Noeller!",
"title": "İyi Bayramlar"
}
]
}'

Technical Notes

Database Collections

CollectionUsed forData touched by this endpoint
push_{app_id}Push/message recordsStores push message definitions, status, and delivery metadata.
systemlogsAudit trailStores system action records read/written by this endpoint.
appsApplication metadata/configStores app-level settings and metadata read/updated by this endpoint.
push_{credentials_id}Push/message recordsStores push message definitions, status, and delivery metadata.
geosEndpoint data sourceStores endpoint-related records read or modified by this endpoint.
cohortsEndpoint data sourceStores endpoint-related records read or modified by this endpoint.
features.push.test.uidsPush/message recordsStores push message definitions, status, and delivery metadata.
features.push.test.cohortsPush/message recordsStores push message definitions, status, and delivery metadata.
DEFAULTS.max_media_sizeEndpoint data sourceStores endpoint-related records read or modified by this endpoint.
Content lengthEndpoint data sourceStores endpoint-related records read or modified by this endpoint.
Media sizeEndpoint data sourceStores endpoint-related records read or modified by this endpoint.
Button countEndpoint data sourceStores endpoint-related records read or modified by this endpoint.
PersonalizationEndpoint data sourceStores endpoint-related records read or modified by this endpoint.
Triggers arrayEndpoint data sourceStores endpoint-related records read or modified by this endpoint.
Validation timeEndpoint data sourceStores endpoint-related records read or modified by this endpoint.
Database writesEndpoint data sourceStores endpoint-related records read or modified by this endpoint.
SchedulingEndpoint data sourceStores endpoint-related records read or modified by this endpoint.
Response timeEndpoint data sourceStores endpoint-related records read or modified by this endpoint.


Error Handling

Status CodeConditionResponse
200Success - message createdComplete message object
400Missing required parameters{"kind": "ValidationError", "errors": [...]}
400Invalid platform{"kind": "ValidationError", "errors": ["Invalid platform"]}
400No push credentials{"kind": "ValidationError", "errors": ["No push credentials for iOS platform"]}
400Invalid trigger configuration{"kind": "ValidationError", "errors": ["start is required"]}
400Invalid filter (nonexistent geo/cohort){"kind": "ValidationError", "errors": ["No such geo"]}
500Scheduling error{"errors": ["Error while scheduling the message: ..."]}
500Database error{"kind": "ServerError", "errors": ["Server error"]}

Implementation Notes

  1. ID generation: Uses MongoDB ObjectID for _id, ensuring uniqueness
  2. Timezone handling: sctz is timezone offset in minutes (GMT+3 = -180)
  3. Date formats: Accepts epoch milliseconds or ISO 8601 strings
  4. Content inheritance: First content is default, subsequent override by platform/language
  5. Draft workflow: Draft → Edit → Activate (set status to "active") → Schedule
  6. Approval workflow: If Push Approver enabled, active messages go to "inactive" status
  7. Demo messages: demo: true bypasses credential checks, useful for testing
  8. Audit trail: Every create operation logged to systemlogs with full message JSON
  9. Personalization indexes: String indexes map to character positions in message
  10. Filter combination: user, drill, geos, cohorts filters are AND-ed together

Last Updated

February 2026