Nudge replies and summaries

Configure how members reply to nudges, standardize inbound SMS text into typed values, and fetch reply history plus aggregates for dashboards and weekly rollups.

How it works

  1. Set responseType on the nudge (text, number, date, yes/no, or true/false).
  2. Members reply via SMS. BoomTower stores the original message and a deterministic standardizedValue on each chat message linked to the nudge.
  3. Call GET /v1/nudges/{idOrKey}/replies to list replies and optional aggregates (totals, averages, value counts) for a time window.

Replies live on group chats (or 1:1 chats when correlated). Use Groups to attach members and activate nudges on a team.

Response types

responseTypeCanonical valueExample inbound SMS
texttrimmed originalfeeling great today
number6464 oz · about 80 · $1,234.50
date2026-06-156/15/2026 · today · Jun 15
yes/noyesyeah · yep · nope
true/falsetrue1 · on · false

Invalid typed replies are still stored. standardizedValid is false and standardizedValue is empty; the original content is unchanged.

Configure a nudge

Set responseType when creating or patching a nudge. In the admin UI, use Configure nudge → Expected reply type.

PATCH https://api.boomtower.com/v1/nudges/guzzle-your-gallon
X-API-Key: YOUR_ORG_API_KEY
Content-Type: application/json

{
  "data": {
    "responseType": "number"
  }
}

Example: Guzzle your gallon (weekly water total)

HeadRight's Guzzle your gallon nudge (orgNudgeKey: guzzle-your-gallon) asks members how many ounces of water they drank. Set responseType: "number" so replies like 64 oz or about 80 standardize to numeric values you can sum.

Scenario

Alice is on an accountability group. She receives the nudge Mon–Fri at 5 PM and texts back:

  • Mon: 64 oz → standardized 64
  • Tue: 8080
  • Wed: about 96 oz96
  • Thu: 7272
  • Fri: a lot → invalid (not parsed)

Your app fetches replies for the week and reads stats.number.sum for total ounces consumed (312 from the four valid replies).

Fetch this week's replies and stats

GET https://api.boomtower.com/v1/nudges/guzzle-your-gallon/replies?since=2026-06-23T00:00:00Z&until=2026-06-29T23:59:59Z
X-API-Key: YOUR_ORG_API_KEY

Optional query params: groupId (scope to one team), format=raw|stats|both (default both).

Example response (abbreviated)

{
  "success": true,
  "code": 200,
  "data": {
    "nudgeId": "[tenant:nudge]-…",
    "nudgeKey": "guzzle-your-gallon",
    "responseType": "number",
    "since": "2026-06-23T00:00:00Z",
    "until": "2026-06-29T23:59:59Z",
    "replies": [
      {
        "groupId": "[tenant:group]-…",
        "userId": "[tenant:user]-…",
        "userLabel": "Alice Smith",
        "content": "64 oz",
        "createdAt": "2026-06-23T21:04:12Z",
        "standardizedValue": "64",
        "standardizedValid": true
      },
      {
        "content": "80",
        "standardizedValue": "80",
        "standardizedValid": true
      }
    ],
    "stats": {
      "totalReplies": 5,
      "validReplies": 4,
      "invalidReplies": 1,
      "number": {
        "count": 4,
        "sum": 312,
        "average": 78,
        "min": 64,
        "max": 96
      },
      "byUser": {
        "[tenant:user]-ALICE": { "64": 1, "80": 1, "96": 1, "72": 1 }
      }
    }
  }
}

Dashboard snippet (TypeScript)

type NudgeReplies = {
  data: {
    responseType: string;
    stats?: {
      number?: { sum: number; average: number; count: number };
      validReplies: number;
    };
    replies: Array<{
      content: string;
      standardizedValue: string;
      standardizedValid: boolean;
      createdAt: string;
    }>;
  };
};

export async function weeklyWaterOz(
  apiKey: string,
  weekStart: string,
  weekEnd: string,
): Promise<number> {
  const url = new URL('https://api.boomtower.com/v1/nudges/guzzle-your-gallon/replies');
  url.searchParams.set('since', weekStart);
  url.searchParams.set('until', weekEnd);
  url.searchParams.set('format', 'stats');

  const res = await fetch(url, { headers: { 'X-API-Key': apiKey } });
  const body = (await res.json()) as NudgeReplies;
  return body.data.stats?.number?.sum ?? 0;
}

// weeklyWaterOz(apiKey, '2026-06-23T00:00:00Z', '2026-06-29T23:59:59Z') → 312

Other nudge keys

The path accepts a nudge BoomID, bare ksuid, libraryKey, orgNudgeKey, or systemKey. HeadRight org habits use keys like push-ups, booze-check, and daily-commit — see the Nudge library catalog.

NudgeSuggested responseTypeStats you get
Guzzle your gallonnumberWeekly oz sum / avg
Push-upsnumberRep counts per day
Daily commityes/noYes/no tallies
Booze checknumberDrinks per day

Auth and scope

  • X-API-Key — replies are limited to groups in your organization and nudges in your org catalog.
  • Bearer token — tenant-wide access (admin / in-app use).
  • Ambiguous stable keys (same key on multiple nudges) return an error; use the nudge id instead.

API reference

Full OpenAPI schemas: REST API GET /v1/nudges/{id}/replies, APINudgeReply, APINudgeReplyStats.

Public docs URL: https://boomtower.com/docs/nudge-replies

Related: REST API · Groups · Nudge library