API Documentation

Complete API reference for integrating web push notifications

๐Ÿš€

Getting Started

Welcome to the Noti API! This documentation will help you integrate web push notifications into your application.

Base URL: https://noti.sofehaus.com

Quick Example

JavaScript
const response = await fetch('https://noti.sofehaus.com/api/subscribe', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': 'your-api-key-here'
  },
  body: JSON.stringify({
    projectId: 'your-project-id',
    subscription: {
      endpoint: subscription.endpoint,
      keys: {
        p256dh: subscription.keys.p256dh,
        auth: subscription.keys.auth
      }
    }
  })
});
๐Ÿ”

Authentication

All API requests require an API key in the request header. You can find your API key in your project settings.

x-api-key: your-api-key

โš ๏ธ Security Note: Keep your API key secure and never expose it in client-side code. API keys should only be used in server-side applications.

Example Request

curl -X POST https://noti.sofehaus.com/api/subscribe \
  -H "Content-Type: application/json" \
  -H "x-api-key: your-api-key-here" \
  -d '{
    "projectId": "your-project-id",
    "subscription": {
      "endpoint": "https://fcm.googleapis.com/...",
      "keys": {
        "p256dh": "...",
        "auth": "..."
      }
    }
  }'
๐Ÿ“ฑ

Subscriptions

POST

/api/subscribe

Register a push subscription for a project. This endpoint is public and does not require an API key.

Request Body
{
  "projectId": "string",
  "subscription": {
    "endpoint": "string",
    "keys": {
      "p256dh": "string",
      "auth": "string"
    }
  },
  "trackingConsent": true,
  "privacyPolicyVersion": "1.0"
}

Response (200 OK)

{
  "data": {
    "id": "subscription-id",
    "projectId": "project-id",
    "endpoint": "https://fcm.googleapis.com/...",
    "createdAt": "2024-01-01T00:00:00.000Z"
  },
  "message": "Subscription created successfully"
}
GET

/api/vapid/{projectId}

Get the VAPID public key for a project. This endpoint is public and does not require an API key.

Example Request
curl -X GET https://noti.sofehaus.com/api/vapid/your-project-id

Response (200 OK)

{
  "data": {
    "publicKey": "BEl62iUYgUivxIkvtyyXfXXuio5oc8wX_KdqhXfX..."
  }
}
GET

/api/projects/{projectId}/subscriptions

Get all subscriptions for a project. Requires API key authentication.

Example Request
curl -X GET https://noti.sofehaus.com/api/projects/your-project-id/subscriptions \
  -H "x-api-key: your-api-key-here"

Response (200 OK)

{
  "data": [
    {
      "id": "subscription-id",
      "projectId": "project-id",
      "endpoint": "https://fcm.googleapis.com/...",
      "keys": {
        "p256dh": "...",
        "auth": "..."
      },
      "createdAt": "2024-01-01T00:00:00.000Z"
    }
  ],
  "message": "Subscriptions retrieved successfully"
}
๐Ÿ””

Notifications

POST

/api/notifications/send

Send a push notification to subscribers. Supports targeting by segments, topics, or tags.

Request Body
{
  "projectId": "string",
  "notification": {
    "title": "string",
    "message": "string",
    "icon": "string (optional)",
    "badge": "string (optional)",
    "image": "string (optional)",
    "url": "string (optional)",
    "tag": "string (optional)",
    "tags": ["string"] (optional),
    "actions": [
      {
        "action": "string",
        "title": "string",
        "icon": "string (optional)"
      }
    ] (optional),
    "requireInteraction": false (optional),
    "silent": false (optional)
  },
  "audience": "all" | "segment-id",
  "segmentId": "string (optional)",
  "topics": ["string"] (optional),
  "subscriptionTags": ["string"] (optional),
  "templateId": "string (optional)",
  "scheduleAt": "ISO 8601 date (optional)"
}

Response (200 OK)

{
  "data": {
    "success": true,
    "sentCount": 42,
    "notificationId": "notification-id",
    "notification": {
      "title": "Hello",
      "message": "World"
    }
  },
  "message": "Notification sent to 42 subscribers"
}
POST

/api/notifications/schedule

Schedule a notification to be sent at a specific time. Uses the same request body as send, but requires a `scheduleAt` field.

Request Body
{
  "projectId": "string",
  "notification": {
    "title": "Reminder",
    "message": "Don't forget about our event!"
  },
  "scheduleAt": "2024-12-31T23:59:59.000Z",
  "segmentId": "string (optional)"
}

Response (200 OK)

{
  "data": {
    "id": "scheduled-notification-id",
    "projectId": "project-id",
    "payload": {
      "title": "Reminder",
      "message": "Don't forget about our event!"
    },
    "scheduledAt": "2024-12-31T23:59:59.000Z",
    "status": "pending",
    "createdAt": "2024-01-01T00:00:00.000Z"
  },
  "message": "Notification scheduled successfully"
}
๐Ÿ‘ฅ

Segments

Segments allow you to target specific groups of subscribers based on criteria like user properties, behavior, or tags.

GET

/api/segments?projectId={projectId}

List all segments for a project.

Example Request
curl -X GET "https://noti.sofehaus.com/api/segments?projectId=your-project-id" \
  -H "x-api-key: your-api-key-here"

Response (200 OK)

{
  "data": [
    {
      "id": "segment-id",
      "projectId": "project-id",
      "name": "Premium Users",
      "description": "Users with premium subscription",
      "criteria": {
        "tags": ["premium"]
      },
      "subscriptionCount": 150,
      "createdAt": "2024-01-01T00:00:00.000Z"
    }
  ],
  "message": "Segments retrieved successfully"
}
POST

/api/segments

Create a new segment.

Request Body
{
  "projectId": "string",
  "name": "string",
  "description": "string (optional)",
  "criteria": {
    "tags": ["string"] (optional),
    "userAgent": "string (optional)",
    "createdAfter": "ISO 8601 date (optional)",
    "createdBefore": "ISO 8601 date (optional)"
  }
}

Response (200 OK)

{
  "data": {
    "id": "segment-id",
    "projectId": "project-id",
    "name": "Premium Users",
    "description": "Users with premium subscription",
    "criteria": {
      "tags": ["premium"]
    },
    "subscriptionCount": 0,
    "createdAt": "2024-01-01T00:00:00.000Z"
  },
  "message": "Segment created successfully"
}
๐Ÿ“

Templates

Templates allow you to create reusable notification payloads that can be used when sending notifications.

GET

/api/templates?projectId={projectId}

List all templates for a project.

Example Request
curl -X GET "https://noti.sofehaus.com/api/templates?projectId=your-project-id" \
  -H "x-api-key: your-api-key-here"

Response (200 OK)

{
  "data": [
    {
      "id": "template-id",
      "projectId": "project-id",
      "name": "Welcome Notification",
      "description": "Template for welcoming new users",
      "payload": {
        "title": "Welcome!",
        "message": "Thanks for joining us",
        "icon": "https://example.com/icon.png"
      },
      "createdAt": "2024-01-01T00:00:00.000Z"
    }
  ],
  "message": "Templates retrieved successfully"
}
POST

/api/templates

Create a new template.

Request Body
{
  "projectId": "string",
  "name": "string",
  "description": "string (optional)",
  "payload": {
    "title": "string",
    "message": "string",
    "icon": "string (optional)",
    "url": "string (optional)"
  }
}

Response (200 OK)

{
  "data": {
    "id": "template-id",
    "projectId": "project-id",
    "name": "Welcome Notification",
    "description": "Template for welcoming new users",
    "payload": {
      "title": "Welcome!",
      "message": "Thanks for joining us",
      "icon": "https://example.com/icon.png"
    },
    "createdAt": "2024-01-01T00:00:00.000Z"
  },
  "message": "Template created successfully"
}
๐Ÿงช

A/B Testing

Create and manage A/B tests to compare different notification variants and determine which performs better.

GET

/api/ab-tests?projectId={projectId}

List all A/B tests for a project.

Example Request
curl -X GET "https://noti.sofehaus.com/api/ab-tests?projectId=your-project-id" \
  -H "x-api-key: your-api-key-here"

Response (200 OK)

{
  "data": [
    {
      "id": "test-id",
      "projectId": "project-id",
      "name": "Subject Line Test",
      "status": "running",
      "variants": {
        "variant-a": {
          "name": "Variant A",
          "payload": {
            "title": "Special Offer!",
            "message": "Get 20% off today"
          }
        },
        "variant-b": {
          "name": "Variant B",
          "payload": {
            "title": "Limited Time Deal",
            "message": "Save 20% now"
          }
        }
      },
      "results": {
        "variant-a": {
          "sent": 50,
          "opened": 25,
          "clicked": 10,
          "openRate": 50.0,
          "clickRate": 20.0
        },
        "variant-b": {
          "sent": 50,
          "opened": 30,
          "clicked": 15,
          "openRate": 60.0,
          "clickRate": 30.0
        }
      },
      "winner": "variant-b",
      "createdAt": "2024-01-01T00:00:00.000Z"
    }
  ],
  "message": "A/B tests retrieved successfully"
}
POST

/api/ab-tests

Create a new A/B test.

Request Body
{
  "projectId": "string",
  "name": "Subject Line Test",
  "variants": {
    "variant-a": {
      "name": "Variant A",
      "payload": {
        "title": "Special Offer!",
        "message": "Get 20% off today"
      }
    },
    "variant-b": {
      "name": "Variant B",
      "payload": {
        "title": "Limited Time Deal",
        "message": "Save 20% now"
      }
    }
  }
}

Response (200 OK)

{
  "data": {
    "id": "test-id",
    "projectId": "project-id",
    "name": "Subject Line Test",
    "status": "draft",
    "variants": {
      "variant-a": {
        "name": "Variant A",
        "payload": {
          "title": "Special Offer!",
          "message": "Get 20% off today"
        }
      },
      "variant-b": {
        "name": "Variant B",
        "payload": {
          "title": "Limited Time Deal",
          "message": "Save 20% now"
        }
      }
    },
    "createdAt": "2024-01-01T00:00:00.000Z"
  },
  "message": "A/B test created successfully"
}
POST

/api/ab-tests/{testId}/send

Send an A/B test to subscribers.

Example Request
curl -X POST https://noti.sofehaus.com/api/ab-tests/test-id/send \
  -H "Content-Type: application/json" \
  -H "x-api-key: your-api-key-here"

Response (200 OK)

{
  "data": {
    "success": true,
    "sentCount": 100,
    "variantA": {
      "sent": 50,
      "notificationId": "notification-id-a"
    },
    "variantB": {
      "sent": 50,
      "notificationId": "notification-id-b"
    }
  },
  "message": "A/B test sent to 100 subscribers"
}
๐Ÿ”„

Recurring Notifications

Set up notifications that automatically repeat on a schedule (daily, weekly, monthly, etc.).

GET

/api/recurring?projectId={projectId}

List all recurring notifications for a project.

Example Request
curl -X GET "https://noti.sofehaus.com/api/recurring?projectId=your-project-id" \
  -H "x-api-key: your-api-key-here"

Response (200 OK)

{
  "data": [
    {
      "id": "recurring-id",
      "projectId": "project-id",
      "name": "Daily Newsletter",
      "payload": {
        "title": "Daily Update",
        "message": "Here's your daily news"
      },
      "schedule": {
        "frequency": "daily",
        "time": "09:00",
        "timezone": "UTC"
      },
      "status": "active",
      "nextRunAt": "2024-01-02T09:00:00.000Z",
      "createdAt": "2024-01-01T00:00:00.000Z"
    }
  ],
  "message": "Recurring notifications retrieved successfully"
}
POST

/api/recurring

Create a new recurring notification.

Request Body
{
  "projectId": "string",
  "name": "Daily Newsletter",
  "payload": {
    "title": "Daily Update",
    "message": "Here's your daily news"
  },
  "schedule": {
    "frequency": "daily",
    "time": "09:00",
    "timezone": "UTC"
  },
  "segmentId": "string (optional)"
}

Response (200 OK)

{
  "data": {
    "id": "recurring-id",
    "projectId": "project-id",
    "name": "Daily Newsletter",
    "payload": {
      "title": "Daily Update",
      "message": "Here's your daily news"
    },
    "schedule": {
      "frequency": "daily",
      "time": "09:00",
      "timezone": "UTC"
    },
    "status": "active",
    "nextRunAt": "2024-01-02T09:00:00.000Z",
    "createdAt": "2024-01-01T00:00:00.000Z"
  },
  "message": "Recurring notification created successfully"
}
๐Ÿ”—

Webhooks

Configure webhooks to receive real-time updates about notification delivery, clicks, opens, and failures.

GET

/api/webhooks?projectId={projectId}

List all webhooks for a project.

Example Request
curl -X GET "https://noti.sofehaus.com/api/webhooks?projectId=your-project-id" \
  -H "x-api-key: your-api-key-here"

Response (200 OK)

{
  "data": [
    {
      "id": "webhook-id",
      "projectId": "project-id",
      "url": "https://your-server.com/webhook",
      "events": ["delivery", "click", "open", "failure"],
      "status": "active",
      "createdAt": "2024-01-01T00:00:00.000Z"
    }
  ],
  "message": "Webhooks retrieved successfully"
}
POST

/api/webhooks

Create a new webhook.

Request Body
{
  "projectId": "string",
  "url": "https://your-server.com/webhook",
  "events": ["delivery", "click", "open", "failure"],
  "secret": "string (optional)"
}

Response (200 OK)

{
  "data": {
    "id": "webhook-id",
    "projectId": "project-id",
    "url": "https://your-server.com/webhook",
    "events": ["delivery", "click", "open", "failure"],
    "status": "active",
    "createdAt": "2024-01-01T00:00:00.000Z"
  },
  "message": "Webhook created successfully"
}
๐Ÿ“Š

Metrics

Retrieve analytics and metrics about your notifications, including delivery rates, click rates, and open rates.

GET

/api/metrics/{projectId}

Get metrics for a project.

Response (200 OK)

{
  "data": {
    "totalSubscriptions": 100,
    "activeSubscriptions": 95,
    "totalSent": 1000,
    "totalDelivered": 950,
    "totalClicks": 150,
    "totalOpens": 200,
    "deliveryRate": 95.0,
    "clickRate": 15.0,
    "openRate": 20.0
  }
}
โš ๏ธ

Error Handling

The API uses standard HTTP status codes and returns error messages in a consistent format.

400 Bad Request

Invalid request parameters or missing required fields.

{
  "error": "Project ID is required"
}

401 Unauthorized

Invalid or missing API key.

{
  "error": "Invalid or missing API key"
}

404 Not Found

Resource not found (project, subscription, etc.).

{
  "error": "Project not found"
}

500 Internal Server Error

An unexpected error occurred on the server.

{
  "error": "An error occurred",
  "message": "Detailed error message"
}