Notifications
Manage your in-app notification feed and configure delivery preferences per event category.
List Notifications
GET /v1/notificationsReturns a paginated list of notifications for the authenticated tenant, ordered by most recent first.
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
limit | integer | No | 50 | Max records to return |
offset | integer | No | 0 | Records to skip |
unread_only | boolean | No | false | When true, returns only unread notifications |
Example Request
curl "https://api.rymi.live/v1/notifications?limit=20&unread_only=true" \
-H "Authorization: Bearer YOUR_API_KEY"Response 200
{
"data": [
{
"id": "notif_abc123",
"tenant_id": "550e8400-...",
"event_category": "billing.low_balance",
"title": "Your balance is getting low",
"message": "Your account has about 12 minutes remaining. Add credits now to keep your agents online.",
"is_read": false,
"metadata": {},
"created_at": "2026-04-01T14:30:00Z"
}
],
"total": 1,
"offset": 0,
"limit": 20
}Errors
| Status | Meaning |
|---|---|
401 | Missing or invalid API key |
Mark All as Read
PUT /v1/notifications/read-allMarks all unread notifications as read for the authenticated tenant. No request body required.
Example Request
curl -X PUT https://api.rymi.live/v1/notifications/read-all \
-H "Authorization: Bearer YOUR_API_KEY"Response 200
{
"success": true
}Errors
| Status | Meaning |
|---|---|
401 | Missing or invalid API key |
Mark Notification as Read
PUT /v1/notifications/:id/readMarks a single notification as read. Idempotent — marking an already-read or unknown ID still returns 200.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Notification ID |
Example Request
curl -X PUT https://api.rymi.live/v1/notifications/notif_abc123/read \
-H "Authorization: Bearer YOUR_API_KEY"Response 200
{
"success": true
}Errors
| Status | Meaning |
|---|---|
401 | Missing or invalid API key |
Delete Notifications
DELETE /v1/notifications/:idRemoves a single notification from your in-app feed. Deletion is tenant-scoped and idempotent — an ID that doesn't exist (or belongs to another tenant) is a no-op that still returns 200.
DELETE /v1/notifications/readClears all read notifications from your in-app feed. The unread set is left untouched.
Response 200
{ "success": true }Delivery History
GET /v1/notifications/deliveriesLists per-channel delivery attempts joined to the source notification. Useful for debugging "why didn't this fire?" — each row shows the channel, status (queued / sent / failed), and the parent notification metadata.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 50 | Max records |
offset | integer | 0 | Records to skip |
channel | string | — | Filter to in_app, email, sms, or webhook |
status | string | — | Filter by delivery status |
event_category | string | — | Filter by source event category |
Response 200
{
"data": [
{
"id": "del_...",
"notification_id": "notif_...",
"channel": "email",
"status": "sent",
"attempt_count": 1,
"last_error": null,
"notification": {
"id": "notif_...",
"event_category": "billing.low_balance",
"title": "Low Balance Warning",
"created_at": "..."
}
}
],
"total": 1,
"offset": 0,
"limit": 50
}Runtime Status
GET /v1/notifications/statusReturns the notification dispatcher's runtime state — useful for the dashboard's "notifications healthy?" indicator. Reports queue depth and per-channel readiness.
Response 200
{
"queue_depth": 0,
"channels": {
"email": { "ready": true },
"sms": { "ready": false, "reason": "TWILIO_NOT_CONFIGURED" },
"in_app": { "ready": true },
"webhook": { "ready": true }
}
}Get Notification Preferences
GET /v1/notifications/preferencesReturns delivery preferences for each event category. Preferences control which channels (email, SMS, in-app, webhook) receive notifications.
Event Categories
Notification event categories are distinct from webhook events:
| Group | Categories |
|---|---|
| Billing | billing.low_balance, billing.balance_depleted, billing.payment_failed, billing.topup_confirmed, billing.invoice_ready |
| Calls | call.first_call, call.daily_summary, call.monthly_summary, call.volume_spike |
| Agents | agent.published, agent.failed, agent.degraded, agent.number_assigned |
| System | system.api_key_created, system.api_key_revoked, system.login_new_device, system.maintenance |
| Team | team.member_invited, team.member_joined |
| Other | auth.welcome, number.porting_complete |
Emails for billing.low_balance, billing.balance_depleted, agent.failed, and agent.degraded are rate-limited to one per category per 24 hours so a flapping condition can't flood an inbox.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
scope | enum | tenant | tenant returns the tenant-wide config; all returns tenant + per-user overrides merged |
Example Request
curl https://api.rymi.live/v1/notifications/preferences \
-H "Authorization: Bearer YOUR_API_KEY"Response 200
{
"data": [
{
"event_category": "billing.low_balance",
"email_enabled": true,
"sms_enabled": false,
"in_app_enabled": true,
"webhook_enabled": false
},
{
"event_category": "agent.failed",
"email_enabled": true,
"sms_enabled": false,
"in_app_enabled": true,
"webhook_enabled": true
}
],
"scope": "tenant"
}Errors
| Status | Meaning |
|---|---|
401 | Missing or invalid API key |
Update Notification Preference
PUT /v1/notifications/preferencesUpdate tenant-wide delivery channels for a specific event category. Creates the preference if it doesn't exist. Only tenant owners and admins can update tenant-wide preferences — other members get a 403 (they can still set personal overrides).
Request Body
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
event_category | string | Yes | — | Event category to configure (e.g., billing.low_balance, agent.failed) |
email_enabled | boolean | No | Unchanged | Enable or disable email delivery |
sms_enabled | boolean | No | Unchanged | Enable or disable SMS delivery |
in_app_enabled | boolean | No | Unchanged | Enable or disable in-app notification |
webhook_enabled | boolean | No | Unchanged | Enable or disable webhook delivery |
Example Request
curl -X PUT https://api.rymi.live/v1/notifications/preferences \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"event_category": "billing.low_balance",
"email_enabled": true,
"sms_enabled": true,
"in_app_enabled": true,
"webhook_enabled": false
}'Response 200
{
"data": {
"event_category": "billing.low_balance",
"email_enabled": true,
"sms_enabled": true,
"in_app_enabled": true,
"webhook_enabled": false
}
}Errors
| Status | Meaning |
|---|---|
400 | Missing event_category |
401 | Missing or invalid API key |
403 | Caller is not a tenant owner or admin |
Personal Preferences
GET /v1/notifications/preferences/me
PUT /v1/notifications/preferences/mePer-user overrides on top of the tenant-wide preferences. Useful when one user wants email alerts while the rest of the team prefers in-app only. The body shape mirrors the tenant-scoped endpoint above.
GET Response 200
{
"data": [
{
"event_category": "billing.low_balance",
"email_enabled": true,
"sms_enabled": false,
"in_app_enabled": true,
"webhook_enabled": false
}
],
"scope": "user"
}Send Test Notification
POST /v1/notifications/testTriggers a test notification to verify your notification delivery pipeline. Useful for testing preference channels. The body is optional — with no body, a simulated billing.low_balance notification is produced through your normal preferences.
Request Body (optional)
| Field | Type | Description |
|---|---|---|
event_category | string | Category to simulate (default billing.low_balance) |
title | string | Override the notification title |
message | string | Override the notification message |
requested_channels | string[] | Restrict delivery to these channels (in_app, email, sms, webhook); preferences still apply |
force_channels | string[] | Deliver to these channels even if preferences disable them — useful to test a channel before enabling it |
Example Request
curl -X POST https://api.rymi.live/v1/notifications/test \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "force_channels": ["email"] }'Response 200
{
"success": true,
"jobId": "job_notif_123"
}Errors
| Status | Meaning |
|---|---|
401 | Missing or invalid API key |
500 | Notification service not configured |

