Send a notification

POST/api/public/notifications

Send an in-app notification to one trainee, immediately or on a schedule. Requires the notifications:send scope, which is separate from messaging:send (WhatsApp). Each trainee accepts at most 10 API-sent notifications per day; over that the endpoint returns 429. High-risk — anyone with the key can deliver push notifications to your trainees.

Authentication

Requires an API key, sent as Authorization: Bearer cp_live_....

API keys carry scopes. Get the catalog of scopes and webhook events lists every scope.

Header parameters

Header parameters
NameTypeDescription
Idempotency-Keystring

Optional. Send a unique key (e.g. a UUID) to make this POST safe to retry. The same key within 24h returns the original result instead of creating a duplicate.

Request body

application/json, required

Request body fields
NameTypeDescription
traineeIdrequiredstring
titlerequiredstring

Short notification title

messagerequiredstring

Body text

typestring

Delivery style. "push" (default) is a standard push notification, "popup" shows an in-app popup card, "both" sends a push and shows the popup. Never sends WhatsApp.

Allowed values: push popup both

popupDataobject

Content of the in-app popup card. Only used when type is "popup" or "both".

popupData.titlestring
popupData.descriptionstring
popupData.videoLinkstring
popupData.actionLinkstring

URL opened when the call-to-action button is pressed

popupData.buttonTextstring

Call-to-action button label

popupData.imageUrlstring
popupData.dismissibleboolean

Whether the trainee can dismiss the popup. Defaults to true.

scheduledAtstring

Shorthand for a single future delivery: an ISO date-time. Use schedule instead for recurring sends. Cannot be combined with schedule.

scheduleobject

Deliver later, optionally repeating. Omit both schedule and scheduledAt to send immediately. Cannot be combined with scheduledAt.

schedule.startDaterequiredstring

First send date, ISO-8601. Either a date ("2026-06-15") or a full date-time.

schedule.timeOfDayrequiredstring

Local time of day in 24h "HH:mm" format, e.g. "09:30"

Pattern: ^([01]?[0-9]|2[0-3]):[0-5][0-9]$

schedule.frequencystring

Defaults to "once" (a single future send). Any other value repeats until endDate.

Allowed values: once daily weekly biweekly triweekly monthly

schedule.weeklyDaysnumber[]

0=Sunday..6=Saturday. Required for weekly, biweekly and triweekly.

schedule.monthlyModestring

For monthly: byDate uses monthlyDays, byWeekday uses monthlyWeekday plus monthlyWeekOfMonth. Defaults to byDate.

Allowed values: byDate byWeekday

schedule.monthlyDaysnumber[]

Days of the month for monthly byDate

schedule.monthlyWeekdaynumber

0=Sunday..6=Saturday for monthly byWeekday

Minimum: 0

Maximum: 6

schedule.monthlyWeekOfMonthnumber

1-4, or -1 for the last week of the month

Allowed values: 1 2 3 4 -1

schedule.endDatestring

Optional ISO date that stops a recurring schedule

schedule.timezonestring

IANA timezone. Defaults to Asia/Jerusalem.

Request examples

cURL
curl --request POST \
  --url 'https://api.coach-platform.com/api/public/notifications' \
  --header 'Authorization: Bearer cp_live_...' \
  --header 'Content-Type: application/json' \
  --data '{
  "traineeId": "<string>",
  "title": "<string>",
  "message": "<string>"
}'
JavaScript (fetch)
const response = await fetch('https://api.coach-platform.com/api/public/notifications', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer cp_live_...',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "traineeId": "<string>",
    "title": "<string>",
    "message": "<string>"
  }),
});

const data = await response.json();

Responses

201 Created

Example body (application/json)
{
  "data": {
    "id": "<string>",
    "type": "push",
    "status": "sent",
    "recipients": 123,
    "scheduledFor": "<string>"
  },
  "warnings": [
    {
      "field": "<string>",
      "message": "<string>"
    }
  ]
}
Response fields (9)
Response fields
NameTypeDescription
dataobject
data.idstring | null
data.typestring

Allowed values: push popup both

data.statusstring

Allowed values: sent scheduled

data.recipientsnumber

How many trainees the notification was delivered to

data.scheduledForstring | null

ISO date-time of the first delivery when scheduled

warningsobject[]

Non-fatal problems with follow-up writes. The resource was created, but each listed field was not applied.

warnings[].fieldstring
warnings[].messagestring

Error responses

  • 400 Bad Request
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
  • 409 Conflict
  • 429 Too Many Requests
  • 500 Internal Server Error

These statuses share the same response body.

Example body (application/json)
{
  "error": {
    "code": "<string>",
    "message": "<string>",
    "fix": "<string>",
    "details": {},
    "retryAfterMs": 123
  }
}
Error fields (6)
Error fields
NameTypeDescription
errorobject
error.codestring
error.messagestring
error.fixstring | null
error.detailsobject | null
error.retryAfterMsnumber | null

This page is also available as Markdown. Browse it in the interactive explorer or download the OpenAPI spec.