Send a push notification
Sends a push notification to the devices of the persons named by personIds and distinctIds, and answers 202 while the deliveries continue in the background; follow them with GET .../push-notifications/{pushNotificationId}/deliveries.
Distinct ids that name no person are reported in unresolvedDistinctIds, not refused. Devices of a push service the project has not enabled are skipped. Repeating a send with the same Idempotency-Key header returns the first one instead of sending again.
Guide: Push notifications
A project secret key: vh_sk_... for production, vh_sk_test_... for test. Keep it on your servers.
In: header
Path parameters
The project's id, proj_.... A secret key works only in the project it belongs to.
Header parameters
Repeating a send with the same key returns the first send instead of sending again.
Request body
application/json
TypeScript definitions
Use the request body type in TypeScript.
Ids of persons to notify on every device they registered; at least one of personIds and distinctIds is required.
Distinct ids of persons to notify; ones that name no person are reported in unresolvedDistinctIds, not refused.
The notification's title.
1 <= lengthThe notification's text.
1 <= lengthCustom data delivered to the app with the notification. Through FCM, values other than strings arrive JSON-encoded.
The sound to play, such as default.
The number to show on the app icon on Apple devices.
high asks the push service to deliver at once; default lets it deliver when it saves the device power. Defaults to default.
How many seconds the Apple Push Notification service keeps trying to deliver it to a device registered with APNs. FCM uses the configuration's androidTtl instead.
The Android notification channel to post it in.
Notifications with the same collapse id replace each other on a device.
Examples
curl -X POST "https://api.voidhash.com/api/v1/projects/proj_tz4a98xxat96iws9zmbrgj3a/push-notifications" \ -H "idempotency-key: trial-ending-2026-03-14-user_8231" \ -H "Authorization: Bearer vh_sk_..." \ -H "Content-Type: application/json" \ -d '{ "distinctIds": [ "user_8231" ], "title": "Your trial ends tomorrow", "body": "Keep Pro for $4.99 a month.", "data": { "screen": "paywall" }, "priority": "high" }'{ "id": "push_send_r2t6y0u4i8o1p5a9s3d7f1g5", "status": "pending", "deviceCount": 2, "unresolvedDistinctIds": []}{ "error": { "type": "invalid_request", "code": "recipients_required", "message": "Name at least one recipient in personIds or distinctIds.", "param": "personIds" }}{ "error": { "type": "unauthenticated", "code": "invalid_api_key", "message": "This secret key is not valid." }}{ "error": { "type": "permission_denied", "code": "push_notifications_not_enabled", "message": "Push notifications are not enabled for this organization." }}{ "error": { "type": "not_found", "code": "project_not_found", "message": "There is no project proj_tz4a98xxat96iws9zmbrgj3a, or this credential cannot use it.", "param": "projectId" }}{ "error": { "type": "conflict", "code": "push_notifications_not_configured", "message": "This project has no enabled push notification configuration; enable FCM or APNs first." }}{ "error": { "type": "internal", "code": "internal_error", "message": "Something went wrong on our side. Try again, and contact support with the Request-Id header if it keeps failing." }}Response body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
Errors
| Status | type | code | When |
|---|---|---|---|
| 400 | invalid_request | recipients_required | Without at least one person. |
| 403 | permission_denied | push_notifications_not_enabled | When push notifications are not enabled for the organization. |
| 409 | conflict | push_notifications_not_configured | When the project has no enabled push service. |
It can also fail with the errors every operation shares, such as unauthenticated; see Errors.
More in Push notifications
Something wrong or missing on this page? Tell us by email or on Discord.