API Reference
Complete REST API reference for Notifs. While we recommend using our official SDK, you can also integrate directly with our REST API.
Base URL
https://notifs.io/api
Authentication
API Key Authentication
Management endpoints (create webhook, get webhook) use API key authentication:
Authorization: ntf_live_your_api_key
API keys can be created in your dashboard. Keys start with ntf_live_ (production) or ntf_test_ (development).
Signature Authentication
The notification endpoint (POST /webhook/:webhookId) uses signature-based authentication instead of API keys. This ensures only your server can trigger notifications. See Send Notification for details.
Example Request
curl https://notifs.io/api/webhooks/your-webhook-id \
-H "Authorization: ntf_live_your_api_key"
Rate Limits
Rate limits are enforced per API key:
| Plan | Rate Limit | Header |
|------|------------|--------|
| Free | 10 req/sec | X-RateLimit-Limit: 10 |
| Pro | 100 req/sec | X-RateLimit-Limit: 100 |
| Enterprise | Custom | X-RateLimit-Limit: <custom> |
Rate Limit Headers
All responses include rate limit information:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640995200
Webhooks
Send Notification (Consumer Endpoint)
Send a notification through your webhook. This endpoint uses signature-based authentication (not API key) for security.
Endpoint: POST /webhook/:webhookId
Parameters:
webhookId(path, required): The webhook ID (UUID format)
Headers:
Content-Type: application/json(required)X-Notifs-Signature: t=<timestamp>,v1=<hash>(required) - HMAC-SHA256 signature
Request Body:
Any valid JSON payload. Common fields used by services:
{
"title": "Payment Received",
"message": "You received a payment of $99.00",
"data": {
"user": "john@example.com",
"amount": "$99.00",
"orderId": "order_123"
}
}
Response: 200 OK
{
"message": "Webhook processed successfully",
"notificationId": "550e8400-e29b-41d4-a716-446655440000",
"servicesExecuted": true,
"usageInfo": {
"current": 5,
"limit": 105,
"inGracePeriod": false
}
}
Error Responses:
| Status | Code | Description |
|--------|------|-------------|
| 401 | invalid_signature | Invalid or missing signature |
| 402 | quota_exceeded | Usage limit exceeded |
| 409 | replay_attack_detected | Duplicate request within 5 minutes |
| 429 | webhook_rate_limit | Rate limit exceeded |
Example (using SDK - recommended):
import { Notifs } from '@notifs/sdk'
const notifs = new Notifs({ apiKey: process.env.NOTIFS_API_KEY })
const webhook = await notifs.webhooks.get('your_webhook_id')
await webhook.send({
title: 'Payment Received',
message: 'You received a payment of $99.00',
data: { user: 'john@example.com', amount: '$99.00' }
})
Note: We strongly recommend using the SDK which handles signature generation automatically. For manual signature generation, see the Security documentation.
Get Webhook
Retrieve webhook configuration and secret.
Endpoint: GET /webhooks/:webhookId
Authentication: API key or session
Response: 200 OK
{
"success": true,
"webhook": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Payment Notifications",
"project_id": "project_abc123",
"user_id": "user_xyz",
"webhook_secret": "your-webhook-secret-uuid",
"created_at": "2024-01-01T00:00:00.000Z",
"updated_at": "2024-01-01T00:00:00.000Z"
}
}
Example:
curl https://notifs.io/api/webhooks/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: ntf_live_your_api_key"
List Webhooks
Coming Soon: This endpoint is not yet available via the REST API. Webhooks can be listed via the dashboard or using the SDK's
webhooks.list()method.
Create Webhook
Create a new webhook.
Endpoint: POST /webhooks
Authentication: API key or session
Request Body:
{
"name": "Payment Notifications",
"projectId": "optional-project-uuid"
}
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| name | string | No | Webhook name (defaults to "New Webhook") |
| projectId | string | No | Associate with a project |
Response: 200 OK
{
"success": true,
"webhook": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Payment Notifications",
"project_id": null,
"user_id": "user_xyz",
"webhook_secret": "your-new-webhook-secret",
"created_at": "2024-01-01T00:00:00.000Z",
"updated_at": "2024-01-01T00:00:00.000Z"
}
}
Example:
curl -X POST https://notifs.io/api/webhooks \
-H "Authorization: ntf_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{"name": "Order Notifications"}'
Note: Store the
webhook_secretsecurely. It's used to sign requests when sending notifications.
Update Webhook
Coming Soon: Update endpoint is not yet available via the REST API. Webhooks can be updated via the dashboard.
Delete Webhook
Coming Soon: Delete endpoint is not yet available via the REST API. Webhooks can be deleted via the dashboard.
Regenerate Secret
Regenerate the webhook secret. This immediately invalidates the old secret.
Endpoint: POST /webhooks/:webhookId/regenerate-secret
Authentication: Session only (dashboard)
Response: 200 OK
{
"success": true,
"data": {
"webhook_secret": "new-webhook-secret-here"
}
}
Test Webhook
Send a test notification through your webhook to verify it's configured correctly.
Endpoint: POST /webhooks/:webhookId/test
Authentication: Session only (dashboard)
Response: 200 OK
{
"success": true,
"status": 200,
"data": {
"message": "Webhook processed successfully",
"notificationId": "550e8400-e29b-41d4-a716-446655440000"
}
}
Logs
Get Webhook Logs
Retrieve request logs for a specific webhook.
Endpoint: GET /webhooks/:webhookId/logs
Authentication: Session only (dashboard)
Query Parameters:
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| limit | number | 50 | Number of results to return |
| offset | number | 0 | Pagination offset |
| status | string | - | Filter by status: success or error |
Response: 200 OK
{
"success": true,
"data": {
"logs": [
{
"id": "log-uuid",
"webhook_id": "webhook-uuid",
"request_body": { "title": "Test", "data": {} },
"response_status": 200,
"response_body": { "message": "Webhook processed successfully" },
"signature_provided": "t=1234567890,v1=abc123...",
"signature_valid": true,
"duration_ms": 125,
"created_at": "2024-01-01T00:00:00.000Z"
}
],
"total": 1,
"limit": 50,
"offset": 0
}
}
Example:
curl "https://notifs.io/api/webhooks/550e8400-e29b-41d4-a716-446655440000/logs?limit=20&status=error" \
-H "Cookie: your-session-cookie"
Note: Logs are only accessible via authenticated dashboard sessions, not API keys.
Channels
Notification channels are currently configured via the dashboard. API endpoints for channel configuration are coming soon.
Available Channels
| Channel | Configuration |
|---------|---------------|
| Email | Recipient email address and subject line |
| SMS | Phone number (E.164 format, e.g. +14155551234) |
| Slack | OAuth connection + channel selection (up to 3 channels) |
Error Handling
Management API Errors
Management endpoints (create, get, etc.) return errors in this format:
{
"success": false,
"error": {
"code": "AUTH_1004",
"message": "You must be logged in or provide a valid API key"
}
}
Webhook Consumer Errors
The notification endpoint (POST /webhook/:webhookId) returns errors like:
{
"message": "Invalid webhook signature",
"code": "WEBHOOK_2001",
"reason": "Signature timestamp too old"
}
Error Codes
| Code | Status | Description |
|------|--------|-------------|
| AUTH_1004 | 401 | Unauthorized - invalid or missing credentials |
| WEBHOOK_2001 | 401 | Invalid signature |
| WEBHOOK_2002 | 400 | Payload validation failed |
| WEBHOOK_2003 | 404 | Webhook not found |
| WEBHOOK_2005 | 409 | Replay attack detected (duplicate request) |
| WEBHOOK_2006 | 429 | Webhook rate limit exceeded |
| WEBHOOK_2009 | 413 | Payload too large (max 1MB) |
| SUBSCRIPTION_6005 | 402 | Usage quota exceeded |
| RATE_LIMIT_7003 | 429 | Rate limit exceeded |
| VALIDATION_5001 | 400 | Invalid input |
| DB_4004 | 404 | Resource not found |
| SYSTEM_8001 | 500 | Internal server error |
Rate Limit Error Response
{
"message": "Rate limit exceeded",
"code": "RATE_LIMIT_7003",
"retryAfter": 60
}
Headers included:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1640995200
Replay Protection
Duplicate requests with identical payloads are automatically rejected within a 5-minute window. This prevents accidental duplicate notifications from network retries or application bugs.
If a duplicate is detected, you'll receive:
{
"message": "Duplicate request detected",
"code": "WEBHOOK_2005",
"fingerprint": "abc123...",
"info": "This request was already processed within the last 5 minutes"
}
Status: 409 Conflict
To send the same payload again, wait 5 minutes or modify the payload slightly (e.g., add a timestamp).
Webhook Signatures
When sending notifications via POST /webhook/:webhookId, you must include a signature header:
X-Notifs-Signature: t=<unix_timestamp>,v1=<hmac_sha256_hex>
The signature is computed as:
HMAC-SHA256(webhook_secret, "<timestamp>.<json_payload>")
Important:
- Timestamps must be within 5 minutes of the server time
- The SDK handles signature generation automatically
- See the Security documentation for manual implementation details
Pagination
Endpoints that return lists (like webhook logs) support offset-based pagination:
# First page
curl "https://notifs.io/api/webhooks/webhook-id/logs?limit=50" \
-H "Cookie: your-session-cookie"
# Next page
curl "https://notifs.io/api/webhooks/webhook-id/logs?limit=50&offset=50" \
-H "Cookie: your-session-cookie"
Response includes pagination metadata:
{
"success": true,
"data": {
"logs": [...],
"total": 150,
"limit": 50,
"offset": 0
}
}
Stability
The API is designed for stability. We avoid breaking changes whenever possible, and will communicate any necessary changes well in advance.
SDKs
We recommend using our official SDKs instead of calling the REST API directly:
- TypeScript/JavaScript SDK
- Python SDK (coming soon)
- Go SDK (coming soon)
- Ruby SDK (coming soon)
Support
- Email: api@notifs.io
- GitHub: https://github.com/notifs/sdk/issues
Next Steps
- Explore the SDK Reference for a better developer experience
- Review Security Best Practices
- Check out Examples for common use cases