REST API Reference
Direct HTTP API access for server-side integrations
Use the REST API to integrate Pushary with any language or platform. All endpoints require authentication via API key.
Base URL
https://pushary.com/api/v1/serverAuthentication
All server API endpoints require a full API key passed via the Authorization header:
Authorization: Bearer pk_xxx.sk_xxxThe API key consists of two parts:
pk_xxx- Public prefix (site key)sk_xxx- Secret portion (never expose client-side)
Example Request
curl -X GET https://pushary.com/api/v1/server/subscribers \
-H "Authorization: Bearer pk_abc123.sk_secret456"Authentication Errors
| Status | Error | Description |
|---|---|---|
| 401 | Unauthorized | Missing or invalid API key |
{
"error": "Unauthorized",
"message": "Invalid or missing API key. Use Authorization: Bearer pk_xxx.sk_xxx"
}Rate Limiting
Rate limits vary by plan and are applied per API key:
| Plan | Requests/minute |
|---|---|
| Free | 100 |
| Starter | 200 |
| Growth | 500 |
| Enterprise | 1000 |
Rate Limit Headers
Every response includes rate limit information:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 99
X-RateLimit-Reset: 1704067200Rate Limit Exceeded
{
"error": "Too Many Requests",
"message": "Rate limit exceeded. Please retry after 60 seconds.",
"retryAfter": 60
}Pagination
List endpoints support cursor-based pagination:
| Parameter | Type | Default | Max | Description |
|---|---|---|---|---|
limit | integer | 100 | 500 | Number of items per page |
cursor | string | - | - | Cursor for next page |
Response Format
{
"data": [...],
"hasMore": true,
"nextCursor": "abc123"
}Paginating Results
curl "https://pushary.com/api/v1/server/subscribers?limit=50&cursor=abc123" \
-H "Authorization: Bearer pk_xxx.sk_xxx"Send Notifications
Send push notifications directly to subscribers.
POST /send
curl -X POST https://pushary.com/api/v1/server/send \
-H "Authorization: Bearer pk_xxx.sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"title": "New Message",
"body": "You have a new notification",
"url": "https://example.com/messages"
}'Request Body
| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Notification title |
body | string | Yes | Notification body text |
url | string | No | Click action URL |
iconUrl | string | No | Custom icon URL |
imageUrl | string | No | Large image URL |
subscriberIds | string[] | No | Target specific subscribers |
externalIds | string[] | No | Target by external user IDs |
tags | string[] | No | Target by subscriber tags |
Targeting
If no targeting parameters are provided, the notification is sent to all active subscribers.
curl -X POST https://pushary.com/api/v1/server/send \
-H "Authorization: Bearer pk_xxx.sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"title": "Welcome Back!",
"body": "We missed you",
"externalIds": ["user_123", "user_456"]
}'Response
{
"success": true,
"campaignId": "camp_abc123",
"sent": 150,
"limits": {
"remaining": 9850,
"limit": 10000
}
}Subscribers
Manage push notification subscribers.
List Subscribers
GET /subscribersQuery Parameters
| Parameter | Type | Description |
|---|---|---|
limit | integer | Items per page (default: 100, max: 500) |
cursor | string | Pagination cursor |
status | string | Filter by status: active, unsubscribed, expired, bounced |
externalId | string | Filter by external ID |
tags | string | Comma-separated tags filter |
Example
curl "https://pushary.com/api/v1/server/subscribers?status=active&limit=50" \
-H "Authorization: Bearer pk_xxx.sk_xxx"Response
{
"data": [
{
"id": "sub_abc123",
"siteId": "site_xyz",
"status": "active",
"externalId": "user_123",
"tags": ["premium", "newsletter"],
"browser": "Chrome",
"os": "Windows",
"country": "US",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
}
],
"hasMore": true,
"nextCursor": "sub_def456"
}Get Subscriber
GET /subscribers/:idcurl https://pushary.com/api/v1/server/subscribers/sub_abc123 \
-H "Authorization: Bearer pk_xxx.sk_xxx"Update Subscriber
PATCH /subscribers/:idcurl -X PATCH https://pushary.com/api/v1/server/subscribers/sub_abc123 \
-H "Authorization: Bearer pk_xxx.sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"tags": ["premium", "early-access"],
"externalId": "user_456",
"customData": {"plan": "pro"}
}'Request Body
| Field | Type | Description |
|---|---|---|
tags | string[] | Update subscriber tags |
externalId | string | Update external identifier |
customData | object | Custom metadata |
Delete Subscriber
DELETE /subscribers/:idcurl -X DELETE https://pushary.com/api/v1/server/subscribers/sub_abc123 \
-H "Authorization: Bearer pk_xxx.sk_xxx"Response
{
"success": true
}Get Subscriber Count
GET /subscribers/countcurl https://pushary.com/api/v1/server/subscribers/count \
-H "Authorization: Bearer pk_xxx.sk_xxx"Response
{
"total": 1500,
"active": 1200,
"unsubscribed": 300
}Campaigns
Create and manage notification campaigns.
List Campaigns
GET /campaignscurl "https://pushary.com/api/v1/server/campaigns?limit=20" \
-H "Authorization: Bearer pk_xxx.sk_xxx"Response
{
"data": [
{
"id": "camp_abc123",
"name": "Welcome Campaign",
"title": "Welcome!",
"body": "Thanks for subscribing",
"status": "draft",
"totalTargeted": 0,
"totalSent": 0,
"totalDelivered": 0,
"totalClicked": 0,
"createdAt": "2024-01-15T10:30:00Z"
}
],
"hasMore": false,
"nextCursor": null
}Create Campaign
POST /campaignscurl -X POST https://pushary.com/api/v1/server/campaigns \
-H "Authorization: Bearer pk_xxx.sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"name": "Product Launch",
"title": "New Feature Available!",
"body": "Check out our latest update",
"actionUrl": "https://example.com/new-feature"
}'Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Internal campaign name |
title | string | Yes | Notification title |
body | string | Yes | Notification body |
iconUrl | string | No | Custom icon URL |
imageUrl | string | No | Large image URL |
actionUrl | string | No | Click action URL |
scheduledAt | string | No | ISO 8601 schedule time |
segmentId | string | No | Target segment ID |
Response
Returns the created campaign object with status 201.
Get Campaign
GET /campaigns/:idcurl https://pushary.com/api/v1/server/campaigns/camp_abc123 \
-H "Authorization: Bearer pk_xxx.sk_xxx"Update Campaign
PATCH /campaigns/:idcurl -X PATCH https://pushary.com/api/v1/server/campaigns/camp_abc123 \
-H "Authorization: Bearer pk_xxx.sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"title": "Updated Title",
"body": "Updated body text"
}'Request Body
| Field | Type | Description |
|---|---|---|
name | string | Campaign name |
title | string | Notification title |
body | string | Notification body |
iconUrl | string | Custom icon URL |
imageUrl | string | Large image URL |
actionUrl | string | Click action URL |
scheduledAt | string | ISO 8601 schedule time |
status | string | Campaign status |
Delete Campaign
DELETE /campaigns/:idcurl -X DELETE https://pushary.com/api/v1/server/campaigns/camp_abc123 \
-H "Authorization: Bearer pk_xxx.sk_xxx"Send Campaign
POST /campaigns/:id/sendSend an existing campaign to all active subscribers.
curl -X POST https://pushary.com/api/v1/server/campaigns/camp_abc123/send \
-H "Authorization: Bearer pk_xxx.sk_xxx"Requirements
- Campaign must have status
draftorscheduled - Site must have VAPID keys configured
Response
Returns the updated campaign object with status sending.
Pause Campaign
POST /campaigns/:id/pausePause an active or sending campaign to temporarily stop notifications.
curl -X POST https://pushary.com/api/v1/server/campaigns/camp_abc123/pause \
-H "Authorization: Bearer pk_xxx.sk_xxx"Requirements
- Campaign must have status
activeorsending
Response
Returns the updated campaign object with status paused.
Resume Campaign
POST /campaigns/:id/resumeResume a paused campaign to continue sending notifications.
curl -X POST https://pushary.com/api/v1/server/campaigns/camp_abc123/resume \
-H "Authorization: Bearer pk_xxx.sk_xxx"Requirements
- Campaign must have status
paused
Response
Returns the updated campaign object with status active.
Get Campaign Stats
GET /campaigns/:id/statsGet delivery and engagement statistics for a campaign.
curl https://pushary.com/api/v1/server/campaigns/camp_abc123/stats \
-H "Authorization: Bearer pk_xxx.sk_xxx"Response
{
"totalSent": 1000,
"totalDelivered": 950,
"totalClicked": 85,
"totalFailed": 50,
"deliveryRate": 95.0,
"clickRate": 8.95
}| Field | Type | Description |
|---|---|---|
totalSent | number | Total notifications sent |
totalDelivered | number | Successfully delivered |
totalClicked | number | Clicked by subscribers |
totalFailed | number | Failed deliveries |
deliveryRate | number | Delivery success rate (%) |
clickRate | number | Click-through rate (%) |
Templates
Create reusable notification templates.
List Templates
GET /templatescurl "https://pushary.com/api/v1/server/templates" \
-H "Authorization: Bearer pk_xxx.sk_xxx"Response
{
"data": [
{
"id": "tmpl_abc123",
"name": "Welcome Template",
"title": "Welcome to {{siteName}}!",
"body": "Thanks for subscribing, {{userName}}",
"iconUrl": null,
"imageUrl": null,
"actionUrl": "https://example.com/welcome",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
}
],
"hasMore": false,
"nextCursor": null
}Create Template
POST /templatescurl -X POST https://pushary.com/api/v1/server/templates \
-H "Authorization: Bearer pk_xxx.sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"name": "Order Confirmation",
"title": "Order Confirmed!",
"body": "Your order #{{orderId}} has been confirmed",
"actionUrl": "https://example.com/orders/{{orderId}}"
}'Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Template name |
title | string | Yes | Notification title |
body | string | Yes | Notification body |
iconUrl | string | No | Custom icon URL |
imageUrl | string | No | Large image URL |
actionUrl | string | No | Click action URL |
Get Template
GET /templates/:idcurl https://pushary.com/api/v1/server/templates/tmpl_abc123 \
-H "Authorization: Bearer pk_xxx.sk_xxx"Update Template
PATCH /templates/:idcurl -X PATCH https://pushary.com/api/v1/server/templates/tmpl_abc123 \
-H "Authorization: Bearer pk_xxx.sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"title": "Updated Title",
"body": "Updated body with {{variable}}"
}'Delete Template
DELETE /templates/:idcurl -X DELETE https://pushary.com/api/v1/server/templates/tmpl_abc123 \
-H "Authorization: Bearer pk_xxx.sk_xxx"Flows
Manage automated notification sequences triggered by user behavior.
List Flows
GET /flowsQuery Parameters
| Parameter | Type | Description |
|---|---|---|
limit | integer | Items per page (default: 100, max: 500) |
cursor | string | Pagination cursor |
status | string | Filter by status: draft, active, paused, archived |
Example
curl "https://pushary.com/api/v1/server/flows?status=active" \
-H "Authorization: Bearer pk_xxx.sk_xxx"Response
{
"data": [
{
"id": "flow_abc123",
"siteId": "site_xyz",
"name": "Welcome Series",
"description": "Onboard new subscribers",
"triggerType": "subscription",
"status": "active",
"executionCount": 150,
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z",
"steps": [
{
"id": "step_abc",
"flowId": "flow_abc123",
"stepOrder": 0,
"stepType": "send_notification",
"config": {
"notification": {
"title": "Welcome!",
"body": "Thanks for subscribing"
}
}
}
]
}
],
"hasMore": false,
"nextCursor": null
}Create Flow
POST /flowscurl -X POST https://pushary.com/api/v1/server/flows \
-H "Authorization: Bearer pk_xxx.sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"name": "Welcome Series",
"description": "Onboard new subscribers",
"triggerType": "subscription",
"steps": [
{
"stepType": "send_notification",
"config": {
"notification": {
"title": "Welcome!",
"body": "Thanks for joining"
}
}
},
{
"stepType": "delay",
"config": {
"delay": {
"value": 1,
"unit": "days"
}
}
}
]
}'Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Flow name |
description | string | No | Flow description |
triggerType | string | Yes | One of: notification_click, notification_impression, notification_dismiss, subscription, unsubscription |
triggerCampaignId | string | No | Campaign ID to trigger from (for notification triggers) |
steps | array | No | Array of flow steps |
Step Types
Send Notification:
{
"stepType": "send_notification",
"config": {
"notification": {
"title": "Title",
"body": "Body text",
"iconUrl": "https://example.com/icon.png",
"imageUrl": "https://example.com/image.png",
"actionUrl": "https://example.com/action"
}
}
}Delay:
{
"stepType": "delay",
"config": {
"delay": {
"value": 24,
"unit": "hours"
}
}
}Units: seconds, minutes, hours, days
Exit:
{
"stepType": "exit",
"config": {}
}Response
Returns the created flow object with status 201.
Get Flow
GET /flows/:idcurl https://pushary.com/api/v1/server/flows/flow_abc123 \
-H "Authorization: Bearer pk_xxx.sk_xxx"Update Flow
PATCH /flows/:idcurl -X PATCH https://pushary.com/api/v1/server/flows/flow_abc123 \
-H "Authorization: Bearer pk_xxx.sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"name": "Updated Welcome Series",
"status": "paused",
"steps": [
{
"stepType": "send_notification",
"config": {
"notification": {
"title": "New Welcome Message",
"body": "Updated content"
}
}
}
]
}'Request Body
| Field | Type | Description |
|---|---|---|
name | string | Flow name |
description | string | Flow description |
triggerType | string | Trigger type |
triggerCampaignId | string | Campaign ID |
status | string | Flow status: draft, active, paused, archived |
steps | array | Array of flow steps (replaces all existing steps) |
Delete Flow
DELETE /flows/:idcurl -X DELETE https://pushary.com/api/v1/server/flows/flow_abc123 \
-H "Authorization: Bearer pk_xxx.sk_xxx"Activate Flow
POST /flows/:id/activateActivate a flow to start processing triggers. Flow must have at least one step.
curl -X POST https://pushary.com/api/v1/server/flows/flow_abc123/activate \
-H "Authorization: Bearer pk_xxx.sk_xxx"Requirements
- Flow must have status
draft,paused, orarchived - Flow must have at least one step
Response
Returns the updated flow object with status active.
Pause Flow
POST /flows/:id/pausePause an active flow to temporarily stop processing triggers.
curl -X POST https://pushary.com/api/v1/server/flows/flow_abc123/pause \
-H "Authorization: Bearer pk_xxx.sk_xxx"Response
Returns the updated flow object with status paused.
Error Responses
All errors follow a consistent format:
{
"error": "Error Type",
"message": "Human-readable description"
}Error Codes
| Status | Error | Description |
|---|---|---|
| 400 | Bad Request | Missing required fields or invalid request body |
| 401 | Unauthorized | Invalid or missing API key |
| 403 | Forbidden | Plan limit exceeded or permission denied |
| 404 | Not Found | Resource does not exist |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Unexpected server error |
Plan Limit Error
{
"error": "Notification limit exceeded",
"message": "You've reached your monthly notification limit",
"upgradeUrl": "https://pushary.com/pricing"
}Missing Fields Error
{
"error": "Missing required fields: title, body"
}