Skip to main content

Messages

Apps can send push notifications and emails to users through a durable message queue. Messages are enqueued via the notify() and email() callbacks in server route handlers and agent tools, then delivered asynchronously by a background dispatcher with retry and dead-letter handling.

Message Lifecycle

pending → dispatched → delivered   (success)
pending → dispatched → pending (failure, will retry)
pending → dispatched → dead (max retries exceeded)
dead/failed → pending (manual retry via API)

Channels

ChannelRecipientDelivery Method
pushInformer usernameFCM to all registered devices (Informer GO)
emailEmail addressTenant mail transport (SMTP, Gmail API, Microsoft Graph)

Push notifications include the app's ID automatically — tapping a notification in Informer GO opens the app, optionally at a specific sub-page via the path field.


GET /api/apps/{id}/messages

List messages for an app with optional filters and cursor-based pagination.

Authentication: Required

Permissions Required: Member+ role (write permission)

Path Parameters:

ParameterTypeDescription
idstringApp UUID or natural ID

Query Parameters:

ParameterTypeDefaultDescription
channelstringFilter by channel: push or email
statusstringFilter by status: pending, dispatched, delivered, failed, dead
recipientstringFilter by recipient (exact match)
limitnumber100Max results (1–500)
beforeISO dateCursor: return messages created before this timestamp

Response:

{
"messages": [
{
"id": "uuid",
"channel": "push",
"recipient": "jane",
"payload": {
"title": "Order Shipped",
"body": "Your order #1234 has shipped!",
"path": "/orders/1234"
},
"status": "delivered",
"attempts": 1,
"maxAttempts": 3,
"error": null,
"createdAt": "2026-04-12T14:00:00.000Z",
"processedAt": "2026-04-12T14:00:01.500Z"
}
],
"summary": [
{ "status": "delivered", "count": 42 },
{ "status": "failed", "count": 3 },
{ "status": "dead", "count": 1 }
]
}

The summary provides status counts for the last 30 days (useful for dashboard indicators).

Cursor Pagination:

Use the createdAt of the last message as the before parameter:

// First page
const page1 = await fetch('/api/apps/{id}/messages?limit=50');

// Next page
const lastDate = page1.messages[page1.messages.length - 1].createdAt;
const page2 = await fetch(`/api/apps/{id}/messages?limit=50&before=${lastDate}`);

GET /api/apps/{id}/messages/{messageId}

Get a single message by ID.

Authentication: Required

Permissions Required: Member+ role (write permission)

Path Parameters:

ParameterTypeDescription
idstringApp UUID or natural ID
messageIdstringMessage UUID

Response: Single message object (same shape as items in the list response).

Error Responses:

  • 404 Not Found — Message does not exist or does not belong to this app

POST /api/apps/{id}/messages/{messageId}/_retry

Retry a failed or dead message. Resets the message to pending status with zero attempts so the dispatcher will pick it up again.

Authentication: Required

Permissions Required: Member+ role (write permission)

Path Parameters:

ParameterTypeDescription
idstringApp UUID or natural ID
messageIdstringMessage UUID

Response: The updated message object with status: "pending".

Error Responses:

  • 404 Not Found — Message does not exist
  • 409 Conflict — Message is not in a retryable state (e.g., already pending or delivered)

Sending Messages from App Code

Messages are sent from server route handlers and agent tools using the notify() and email() callbacks. See the handler documentation for full API details.

Quick Reference

// Push notification
const { id } = await notify('username', {
title: 'Alert',
body: 'Something happened',
path: '/details/123' // optional deep link
});

// Email
const { id } = await email('user@example.com', {
subject: 'Report Ready',
html: '<p>Your report is attached.</p>',
from: 'noreply@example.com' // optional
});

// Bulk push
const { ids, queued } = await notify([
{ username: 'alice', title: 'Update', body: '...' },
{ username: 'bob', title: 'Update', body: '...' },
]);

// Bulk email
const { ids, queued } = await email([
{ to: 'alice@example.com', subject: 'Update', html: '...' },
{ to: 'bob@example.com', subject: 'Update', html: '...' },
]);

HAL Relations

RelationDescription
inf:app-messagesLink to the app's message list
inf:app-messageLink to a single message
inf:app-message-retryRetry a failed/dead message