Send from your server
Trigger transactional pushes, such as order updates, from your backend with your project key.
Send pushes from your backend when something happens in your system: an order shipped, a payment failed, a class is about to start. Each call creates a push campaign with the same delivery, report and tap tracking as a dashboard campaign. It shows in Engage › Push with the source api.
Keep the project key on your server. Never put it in an app or a web page.
Authenticate
Send two headers with every request:
| Header | Value |
|---|---|
PROJECT-KEY | Your project key, from Developers › API Key in the dashboard. |
ENVIRONMENT | production or test. The environment the push is sent from. |
These are the same headers as link generation. See Authentication.
Send a push
Medly, a fictional pharmacy app, tells a user their prescription is ready:
curl -X POST https://sdk.sqd.link/api/v1/sdk/server/push \
-H "PROJECT-KEY: $GROVS_PROJECT_KEY" \
-H "ENVIRONMENT: production" \
-H "Content-Type: application/json" \
-d '{
"title": "Your prescription is ready",
"body": "Pick it up at Medly Central today",
"link_id": 4821,
"data": { "order_id": "ord_8812" },
"audience": { "type": "identifiers", "recipients": ["user_1042"] }
}'On self-hosted Grovs, use your own SDK host, such as https://sdk.grovs.example.com.
The response is 202 Accepted with the campaign in status evaluating. Grovs resolves the audience and hands the pushes to Apple and Google within a couple of seconds.
What you can send
The body takes the same message and schedule fields as a dashboard campaign:
| Field | Notes |
|---|---|
title, body | Required. Up to 255 and 1,000 characters. |
name | Optional label in the dashboard. Defaults to the title. |
image_url | Optional. An https:// URL of a PNG, JPEG or GIF. Uploads aren't available here. |
sound | Optional. default or a sound file bundled in your app. |
link_id | Optional. The numeric ID of a Grovs link in this project. |
data | Optional. An object of custom keys, up to 2 KB. |
audience | Required. identifiers (your user IDs), visitors (visitor IDs, the UUIDs Grovs assigns) or segment with a segment_id. Lists hold up to 10,000 entries. |
scheduled_at, local_time, timezone | Optional. Schedule the push instead of sending now, as in Delivery. |
Experiments (variants, control groups and goals) are dashboard-only.
For the full request and response, see the Server push API reference.
Check the result
Save the campaign id from the response and read the live report:
curl https://sdk.sqd.link/api/v1/sdk/server/push/k9Qx2 \
-H "PROJECT-KEY: $GROVS_PROJECT_KEY" \
-H "ENVIRONMENT: production"The report object holds the same numbers as the dashboard report. See Delivery and reporting.
How server pushes differ
- Not held back. Server pushes are transactional. The project control group in Engagement Settings doesn't apply to them.
- Still capped. The daily push cap, if set, counts them like any other push.
- Rate limited. Per project per minute: up to 600 campaigns, 10 of them with a segment audience, and 100,000 listed recipients. Over a limit, the request fails with
429anderror_code: "rate_limited". A refused request creates nothing and uses no budget, so retry after a short wait.
Errors
Every error has an error message. Plan and rate-limit errors also carry an error_code.
| Status | Meaning |
|---|---|
400 | Missing PROJECT-KEY, or ENVIRONMENT isn't production or test. |
403 | Invalid credentials: the project key is wrong. Or, with error_code: "enterprise_required", your Cloud plan doesn't include the server API. |
404 | Push campaigns aren't available on this installation, or no campaign has that ID. |
422 | A field is invalid. The message names it, for example Link not found, Segment not found or data must be an object. |
429 | rate_limited: over one of the per-minute limits above. |