Skip to content

Message API

The Message API sends top-level transient notifications. Use it for alerts, completion messages, image snapshots, price notifications, and other content that does not need later updates or closing.

POST /message

The request body must be JSON. Unknown extension fields are ignored for forward compatibility; known fields that are forbidden for an action are still rejected. If a private Gateway enables PUSHGO_TOKEN, include Authorization: Bearer <token>.

HeaderRequiredDescription
Content-Type: application/jsonYesRequest body format.
Authorization: Bearer <token>Gateway-dependentRequired only when a private Gateway enables PUSHGO_TOKEN.
FieldTypeRequiredDescription
channel_idstringYesTarget channel ID.
passwordstringYesChannel password; trimmed before validation, then 8-128 bytes.
titlestringYesMessage title, must not be empty.
bodystringNoMessage body, Markdown is supported.
op_idstringNoIdempotency key, 1-128 chars, letters/digits/_/:/-.
thing_idstringNoScope the message to a Thing ID; 1-64 chars, letters/digits/_/:/-. The Gateway validates the format but does not require a server-side Thing record.
occurred_atnumber or numeric stringNoUnix seconds or milliseconds accepted and normalized to milliseconds. Required when thing_id is present.
severitystringNocritical, high, normal, low; unknown values normalize to normal.
ttlnumber or numeric stringNoExpiration time; Unix seconds or milliseconds accepted. Provider TTL is capped at 30 days.
urlstringNoOptional click-through URL.
imagesstring[]NoUp to 32 image URLs, max 2048 bytes each.
tagsstring[]NoUp to 32 tags, max 64 bytes each, trimmed and deduplicated.
ciphertextstringNoOptional E2EE ciphertext payload.
metadataobjectNoCustom scalar key-values; key <= 64 bytes, non-empty scalar text <= 512 bytes; nested objects, arrays, and null are rejected.

message_id is generated by the Gateway and is rejected if supplied. Because unknown extension fields are ignored, use the documented names carefully: a misspelled field is not applied.

severityAPNs interruption levelFCM priority
criticalcriticalHIGH
hightime-sensitiveHIGH
normalactiveHIGH
lowpassiveNORMAL
Terminal window
curl -X POST https://gateway.pushgo.dev/message \
-H "Content-Type: application/json" \
-d '{
"channel_id": "YOUR_CHANNEL_ID",
"password": "YOUR_CHANNEL_PASSWORD",
"title": "Backup completed",
"body": "The daily NAS backup has finished.",
"severity": "normal"
}'

If the alert belongs to a persistent entity, pass thing_id and an explicit occurred_at.

{
"channel_id": "YOUR_CHANNEL_ID",
"password": "YOUR_CHANNEL_PASSWORD",
"thing_id": "8a1fc4b3d9f04fd2857f92f66f7cc5d1",
"occurred_at": 1713750000000,
"title": "Home NAS disk warning",
"body": "volume1 usage has reached 92%.",
"severity": "high",
"tags": ["nas", "disk"]
}

If you provide op_id, repeating it with the same normalized payload and scope returns the original result. Reusing it with a different payload or scope returns 409. If omitted, the Gateway generates it.

{
"success": true,
"data": {
"op_id": "00191f23cc000-0123456789abcdef0123456789abcdef",
"message_id": "8a1fc4b3d9f04fd2857f92f66f7cc5d1"
}
}

success=true acknowledges durable Gateway acceptance, not provider success or device display. Store op_id and query GET /send_status/{op_id} when coarse dispatch status matters.

StatusTypical reason
400Missing/invalid required field, forbidden message_id, empty title, or invalid metadata.
401Private Gateway requires a Bearer token, but the header is missing or wrong.
404Channel does not exist or credentials do not match.
409An op_id was reused for a different payload or scope.
413Request body exceeds 32 KiB (32,768 bytes).
503Gateway could not accept the submission.

See Limits & Errors for shared limits.

GET /message is retained for compatibility. It accepts the scalar fields above as query parameters; images and tags are comma-separated, while metadata is a JSON-encoded string. Prefer the JSON POST route for new integrations because URLs, access logs, and browser history can expose the channel password or payload.

PushGo also provides ntfy, Bark, and ServerChan compatibility endpoints for migration. Their field coverage is limited; use native /message when you need thing_id, E2EE, or full PushGo semantics. See Migration Guide.