Container died
api-v2 on vps-01 was killed by the OOM killer and restarted.
- Exit code 137 (out of memory)
- Memory limit: 512 MiB
- Restarted automatically
Each example shows the card as the web app renders it, then the SDK call and the HTTP body that produce it. Copy, change the text and send.
text, metric with a change, list with icons, and buttons: a link that opens in a new tab, and a plugin action that only works in the app. The theme sets the accent color (left border) and the icon.
api-v2 on vps-01 was killed by the OOM killer and restarted.
import { NotificMe } from "@notificme/sdk";
const notific = new NotificMe({ source: "my-service" });
await notific.send({ type: "container.die", severity: "high", summary: "api-v2 died on vps-01 (exit 137)", card: { title: "Container died", theme: { accent: "#E5484D", icon: "🐳" }, blocks: [ { type: "text", text: "api-v2 on vps-01 was killed by the OOM killer and restarted.", }, { type: "metric", label: "Crashes in 24h", value: 3, delta: "+2" }, { type: "list", items: [ { text: "Exit code 137 (out of memory)", icon: "⚠️" }, { text: "Memory limit: 512 MiB", icon: "📦" }, { text: "Restarted automatically", icon: "🔁" }, ], }, { type: "buttons", buttons: [ { label: "Open dashboard", url: "https://dokploy.example.com/project/api" }, { label: "Restart", action: "docker.restart" }, ], }, ], },});{ "source": "my-service", "type": "container.die", "severity": "high", "occurred_at": "2026-11-05T12:00:00Z", "content": { "summary": "api-v2 died on vps-01 (exit 137)", "card": { "title": "Container died", "theme": { "accent": "#E5484D", "icon": "🐳" }, "blocks": [ { "type": "text", "text": "api-v2 on vps-01 was killed by the OOM killer and restarted." }, { "type": "metric", "label": "Crashes in 24h", "value": 3, "delta": "+2" }, { "type": "list", "items": [ { "text": "Exit code 137 (out of memory)", "icon": "⚠️" }, { "text": "Memory limit: 512 MiB", "icon": "📦" }, { "text": "Restarted automatically", "icon": "🔁" } ] }, { "type": "buttons", "buttons": [ { "label": "Open dashboard", "url": "https://dokploy.example.com/project/api" }, { "label": "Restart", "action": "docker.restart" } ] } ] } }}A progress block with steps, sent with live: true and updated with update(). Each update replaces the card in place instead of creating a new notification.
Commit 4c69fac by Jimmy: verification with the authenticator app.
import { NotificMe } from "@notificme/sdk";
const notific = new NotificMe({ source: "my-service" });
const deploy = await notific.send({ type: "deploy.progress", severity: "info", summary: "Deploying api-v2", live: true, card: { title: "Deploy api-v2", theme: { accent: "#FF6A00", icon: "🚀" }, blocks: [ { type: "progress", value: 0.6, steps: ["Build", "Tests", "Push image", "Rollout"], current: 2, }, { type: "text", text: "Commit 4c69fac by Jimmy: verification with the authenticator app.", }, ], },});{ "source": "my-service", "type": "deploy.progress", "severity": "info", "occurred_at": "2026-11-05T12:00:00Z", "card_id": "deploy/api-v2", "content": { "summary": "Deploying api-v2", "card": { "title": "Deploy api-v2", "theme": { "accent": "#FF6A00", "icon": "🚀" }, "blocks": [ { "type": "progress", "value": 0.6, "steps": [ "Build", "Tests", "Push image", "Rollout" ], "current": 2 }, { "type": "text", "text": "Commit 4c69fac by Jimmy: verification with the authenticator app." } ] } }}Two metric blocks, a chart (line, two series) and a table. null cells render as a dash.
| Region | Orders | Change |
|---|---|---|
| BR | 612 | +21% |
| US | 433 | +15% |
| EU | 239 | — |
import { NotificMe } from "@notificme/sdk";
const notific = new NotificMe({ source: "my-service" });
await notific.send({ type: "report.daily", severity: "info", summary: "Daily sales: 1,284 orders (+18%)", card: { title: "Daily sales", blocks: [ { type: "metric", label: "Orders", value: 1284, delta: "+18%" }, { type: "metric", label: "Revenue", value: "48,210", unit: "USD", delta: "+9%", }, { type: "chart", kind: "line", x: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], series: [ { name: "This week", values: [820, 932, 901, 1034, 1190, 1330, 1284] }, { name: "Last week", values: [790, 850, 870, 910, 980, 1100, 1088] }, ], }, { type: "table", columns: ["Region", "Orders", "Change"], rows: [ ["BR", 612, "+21%"], ["US", 433, "+15%"], ["EU", 239, null], ], }, ], },});{ "source": "my-service", "type": "report.daily", "severity": "info", "occurred_at": "2026-11-05T12:00:00Z", "content": { "summary": "Daily sales: 1,284 orders (+18%)", "card": { "title": "Daily sales", "blocks": [ { "type": "metric", "label": "Orders", "value": 1284, "delta": "+18%" }, { "type": "metric", "label": "Revenue", "value": "48,210", "unit": "USD", "delta": "+9%" }, { "type": "chart", "kind": "line", "x": [ "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" ], "series": [ { "name": "This week", "values": [ 820, 932, 901, 1034, 1190, 1330, 1284 ] }, { "name": "Last week", "values": [ 790, 850, 870, 910, 980, 1100, 1088 ] } ] }, { "type": "table", "columns": [ "Region", "Orders", "Change" ], "rows": [ [ "BR", 612, "+21%" ], [ "US", 433, "+15%" ], [ "EU", 239, null ] ] } ] } }}A chart of kind bar and an image by URL (https or a raster data:image).
import { NotificMe } from "@notificme/sdk";
const notific = new NotificMe({ source: "my-service" });
await notific.send({ type: "ci.duration", severity: "low", summary: "CI got slower this week", card: { title: "CI duration (minutes)", blocks: [ { type: "chart", kind: "bar", x: ["web", "server", "sdk", "docs"], series: [ { name: "Last week", values: [4, 7, 2, 1] }, { name: "This week", values: [5, 9, 2, 2] }, ], }, { type: "image", src: "/examples/flamegraph.svg", alt: "Slowest steps of the server pipeline", }, ], },});{ "source": "my-service", "type": "ci.duration", "severity": "low", "occurred_at": "2026-11-05T12:00:00Z", "content": { "summary": "CI got slower this week", "card": { "title": "CI duration (minutes)", "blocks": [ { "type": "chart", "kind": "bar", "x": [ "web", "server", "sdk", "docs" ], "series": [ { "name": "Last week", "values": [ 4, 7, 2, 1 ] }, { "name": "This week", "values": [ 5, 9, 2, 2 ] } ] }, { "type": "image", "src": "/examples/flamegraph.svg", "alt": "Slowest steps of the server pipeline" } ] } }}A question set rendered inside the card: options for a single question with “other”, options for a yesno question, and input for an optional text question, below a table with the context. Level 2 asks for biometrics or the 2FA code.
The CRM cleanup agent found 340 contacts duplicated by e-mail.
| Copies | |
|---|---|
| ana@example.com | 4 |
| bruno@example.com | 3 |
| carla@example.com | 2 |
import { NotificMe } from "@notificme/sdk";
const notific = new NotificMe({ source: "my-service" });
const reply = await notific.ask({ title: "Agent wants to delete 340 duplicate records", questions: [ { id: "action", type: "single", text: "What should we do?", options: ["Approve", "Only the first 10", "Deny"], allowOther: true, }, { id: "backup", type: "yesno", text: "Back up first?" }, { id: "note", type: "text", text: "Instructions for the agent", optional: true, }, ], level: 2, timeout: "30m", onTimeout: { action: "Deny" }, card: { title: "CRM cleanup", theme: { icon: "🤖" }, blocks: [ { type: "text", text: "The CRM cleanup agent found 340 contacts duplicated by e-mail.", }, { type: "table", columns: ["E-mail", "Copies"], rows: [ ["ana@example.com", 4], ["bruno@example.com", 3], ["carla@example.com", 2], ], }, { type: "options", questionId: "action" }, { type: "options", questionId: "backup" }, { type: "input", questionId: "note" }, ], },});
console.log(reply.status, reply.answers, reply.asText);{ "title": "Agent wants to delete 340 duplicate records", "questions": [ { "id": "action", "type": "single", "text": "What should we do?", "options": [ "Approve", "Only the first 10", "Deny" ], "allow_other": true }, { "id": "backup", "type": "yesno", "text": "Back up first?" }, { "id": "note", "type": "text", "text": "Instructions for the agent", "optional": true } ], "level": 2, "timeout": "30m", "on_timeout": { "action": "Deny" }, "card": { "title": "CRM cleanup", "theme": { "icon": "🤖" }, "blocks": [ { "type": "text", "text": "The CRM cleanup agent found 340 contacts duplicated by e-mail." }, { "type": "table", "columns": [ "E-mail", "Copies" ], "rows": [ [ "ana@example.com", 4 ], [ "bruno@example.com", 3 ], [ "carla@example.com", 2 ] ] }, { "type": "options", "question_id": "action" }, { "type": "options", "question_id": "backup" }, { "type": "input", "question_id": "note" } ] }}options for a multi question and input for date, number and voice questions.
import { NotificMe } from "@notificme/sdk";
const notific = new NotificMe({ source: "my-service" });
const reply = await notific.ask({ title: "Release window for api-v2", questions: [ { id: "regions", type: "multi", text: "Which regions?", options: ["BR", "US", "EU"], }, { id: "until", type: "date", text: "Postpone until" }, { id: "batch", type: "number", text: "How many servers per batch?" }, { id: "voice", type: "voice", text: "Anything else? (voice)", optional: true }, ], level: 1, card: { title: "Release window", blocks: [ { type: "options", questionId: "regions" }, { type: "input", questionId: "until" }, { type: "input", questionId: "batch" }, { type: "input", questionId: "voice" }, ], },});
console.log(reply.status, reply.answers, reply.asText);{ "title": "Release window for api-v2", "questions": [ { "id": "regions", "type": "multi", "text": "Which regions?", "options": [ "BR", "US", "EU" ] }, { "id": "until", "type": "date", "text": "Postpone until" }, { "id": "batch", "type": "number", "text": "How many servers per batch?" }, { "id": "voice", "type": "voice", "text": "Anything else? (voice)", "optional": true } ], "level": 1, "card": { "title": "Release window", "blocks": [ { "type": "options", "question_id": "regions" }, { "type": "input", "question_id": "until" }, { "type": "input", "question_id": "batch" }, { "type": "input", "question_id": "voice" } ] }}summary: it is all that a push or a watch shows.buttons link.dedupKey for repeated alerts and live cards for anything with progress.