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.

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"
}
]
}'

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​

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!"

Technical Notes​

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
Implementation details

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.