Docs
grovs.io Start for free

Send from your server

Trigger transactional pushes, such as order updates, from your backend with your project key.

Paid Cloud plans and self-hosted Enterprise · Requires iOS SDK 3.1.0, Android SDK 3.1.0

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:

HeaderValue
PROJECT-KEYYour project key, from Developers › API Key in the dashboard.
ENVIRONMENTproduction 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:

Bash
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:

FieldNotes
title, bodyRequired. Up to 255 and 1,000 characters.
nameOptional label in the dashboard. Defaults to the title.
image_urlOptional. An https:// URL of a PNG, JPEG or GIF. Uploads aren't available here.
soundOptional. default or a sound file bundled in your app.
link_idOptional. The numeric ID of a Grovs link in this project.
dataOptional. An object of custom keys, up to 2 KB.
audienceRequired. 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, timezoneOptional. 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:

Bash
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 429 and error_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.

StatusMeaning
400Missing PROJECT-KEY, or ENVIRONMENT isn't production or test.
403Invalid credentials: the project key is wrong. Or, with error_code: "enterprise_required", your Cloud plan doesn't include the server API.
404Push campaigns aren't available on this installation, or no campaign has that ID.
422A field is invalid. The message names it, for example Link not found, Segment not found or data must be an object.
429rate_limited: over one of the per-minute limits above.
Last updated 2026-10-26
Was this page helpful?