Plush

Plush API

Send customizable, encrypted push notifications to every linked Apple device or one device by name.

Base URLhttps://api.easypush.app
export PLUSH_API_TOKEN="push_..."

curl https://api.easypush.app/v1/devices \
  -H "Authorization: Bearer $PLUSH_API_TOKEN"

Auth

The iOS app can sign in with Apple for a family API token, or register one standalone device and store that API key in Keychain. API calls use bearer auth.

POST /v1/auth/apple App-only exchange for a Sign in with Apple identity token.
{
  "identityToken": "eyJhbGciOi..."
}
POST /v1/auth/standalone App-only registration for one device without Sign in with Apple.
{
  "installationId": "device-local-uuid"
}
POST /v1/tokens/rotate Revoke the current bearer token and return a replacement token.

Devices

Devices register their APNs token and encryption public key. Use the app to edit each device name before targeting it from the API.

GET /v1/devices List enabled devices linked to the Apple account.
POST /v1/devices Register or refresh the current device.
{
  "installationId": "device-local-uuid",
  "name": "workPhone",
  "platform": "iOS",
  "pushToken": "apns-token",
  "publicKey": "base64-public-key",
  "publicKeyAlgorithm": "x25519-hkdf-sha256-aes-gcm",
  "appVersion": "1.0",
  "osVersion": "iOS 18"
}
PATCH /v1/devices/:id Rename or disable a device.
DELETE /v1/devices/:id Remove a device.

Pushes

The simple shape sends a visible APNs alert. Add encrypted envelopes only when you need app-only content.

POST /v1/pushes Send to all devices, named devices, or explicit device IDs.
{
  "title": "Build passed",
  "body": "main deployed successfully"
}
{
  "to": "workPhone",
  "title": "Build passed",
  "body": "main deployed successfully",
  "encrypted": {
    "workPhone": {
      "ciphertext": "...",
      "nonce": "...",
      "tag": "...",
      "ephemeralPublicKey": "...",
      "sentAt": "2026-06-12T00:00:00Z"
    }
  }
}
Target kindShape
allomit to, "all", or { "kind": "all" }
deviceNames"workPhone", ["workPhone"], or { "kind": "deviceNames", "names": ["workPhone"] }
deviceIds{ "kind": "deviceIds", "ids": ["..."] }

Hosted Plush

The hosted service runs at https://api.easypush.app. Use the iOS app to start the hosted flow, subscribe, and reveal the API token stored in Keychain.

Pricing is $1 monthly or $10 yearly. The yearly plan includes a one-week trial before billing starts.

Self-host

The server is a small Cloudflare Worker with D1. Custom deployments can set BILLING_MODE=custom to skip hosted subscription checks.

cd server
npm install
npx wrangler d1 create plush-api
npm run db:migrate:remote
npx wrangler secret put APNS_PRIVATE_KEY
npx wrangler deploy

Errors

Errors return JSON with a message and optional details.

StatusMeaning
401Missing or invalid bearer token.
402Hosted API access needs an active subscription.
422Missing encrypted payloads for a target device.
503APNs credentials are not configured.