Skip to content

Card examples

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.

Push / watchapi-v2 died on vps-01 (exit 137)

Container died

api-v2 on vps-01 was killed by the OOM killer and restarted.

Crashes in 24h3+2
  • Exit code 137 (out of memory)
  • Memory limit: 512 MiB
  • Restarted automatically
Open dashboard ↗Restart
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" },
],
},
],
},
});

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.

Push / watchDeploying api-v2

Deploy api-v2

  1. Build
  2. Tests
  3. Push image
  4. Rollout

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.",
},
],
},
});

Two metric blocks, a chart (line, two series) and a table. null cells render as a dash.

Push / watchDaily sales: 1,284 orders (+18%)

Daily sales

Orders1,284+18%
Revenue48,210 USD+9%
MonSun
This week Last week
RegionOrdersChange
BR612+21%
US433+15%
EU239—
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],
],
},
],
},
});

A chart of kind bar and an image by URL (https or a raster data:image).

Push / watchCI got slower this week

CI duration (minutes)

webdocs
Last week This week
Slowest steps of the server pipeline
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",
},
],
},
});

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.

Push / watchAgent wants to delete 340 duplicate records

CRM cleanup

The CRM cleanup agent found 340 contacts duplicated by e-mail.

E-mailCopies
ana@example.com4
bruno@example.com3
carla@example.com2
What should we do?
Back up first?
Instructions for the agent (optional)
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);

options for a multi question and input for date, number and voice questions.

Push / watchRelease window for api-v2

Release window

Which regions?
Postpone until
How many servers per batch?
Anything else? (voice) (optional)🎙 Hold to record
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);
  • Always write a good summary: it is all that a push or a watch shows.
  • Keep cards short. Put details behind a buttons link.
  • Questions are always native: never ask for a decision with a link or an image.
  • Use dedupKey for repeated alerts and live cards for anything with progress.
  • The web app shows text as plain text: do not rely on markdown or HTML.