SigFollow
Sign in

API reference

Smart template groups

A smart template group bundles several same-shape approved templates. Reference the group by name on the send endpoint and SigFollow picks the best member at send time, so a single template's quality drop never stalls delivery.

Smart template groups are created and managed in the admin console — this page covers the one API surface they expose to integrations: sending a message by group name instead of a specific template name. There are no create / list / update endpoints in the public API; use the System guide to build and maintain groups.

Why send by a group?
A single WhatsApp template is one Meta quality rating away from being throttled or paused. A group holds multiple approved templates that share the same parameter shape; SigFollow rotates to a healthy member automatically, and AI can replenish the group with fresh same-shape variants when quality drops — all invisible to the caller.

Send with a group

POST/v1/:phoneNumberId/messages

Scope: messages:send

Same endpoint as a normal template send — the only difference is that template.group_name replaces template.name. Everything else (path :phoneNumberId, auth, response shape, error body) is identical, so a Meta Cloud API client keeps working after the field swap.

`group_name` is a SigFollow extension
group_nameis not part of Meta's Cloud API schema — it is a SigFollow-only field. SigFollow resolves it to a concrete approved template and strips it before forwarding to Meta, so Meta never sees an unknown key. This means the field only works against the SigFollow gateway, not directly against graph.facebook.com.

Template object

NameTypeRequiredDescription
template.group_namestringyesThe group's display name, exactly as shown in the admin console (per-tenant unique, max 80 chars). Mutually exclusive with template.name — provide one or the other, not both. When set, SigFollow picks a concrete approved member at send time.
template.languageobjectnoOmit in group mode. SigFollow fills language.code from the picked member. (Required only in single-template mode, where you pass template.name.)
template.componentsarraynoVariable substitutions — same schema as a single-template send. Group members share one parameter signature, so the same components array is valid for whichever member is picked. Omit entirely for groups whose templates have no variables.

Example: simple group send

A group whose templates take no variables. Just name the group — no language, no components.

request bodyjson
{
  "messaging_product": "whatsapp",
  "to": "15551234567",
  "type": "template",
  "template": {
    "group_name": "promo group"
  }
}
curl -X POST https://api.sigfollow.com/v1/PHONE_NUMBER_ID/messages \
  -H "Authorization: Bearer sflo_live_xxx" \
  -H "Content-Type: application/json" \
  -d @- <<'JSON'
{
  "messaging_product": "whatsapp",
  "to": "15551234567",
  "type": "template",
  "template": {
    "group_name": "promo group"
  }
}
JSON

Example: group send with body variables

Pass components exactly as you would for a single template. Because every member of a group shares the same parameter signature, the values line up no matter which member SigFollow selects.

request bodyjson
{
  "messaging_product": "whatsapp",
  "to": "15551234567",
  "type": "template",
  "template": {
    "group_name": "promo group",
    "components": [
      {
        "type": "body",
        "parameters": [
          { "type": "text", "text": "Alice" },
          { "type": "text", "text": "ORD-90211" }
        ]
      }
    ]
  }
}
curl -X POST https://api.sigfollow.com/v1/PHONE_NUMBER_ID/messages \
  -H "Authorization: Bearer sflo_live_xxx" \
  -H "Content-Type: application/json" \
  -d @- <<'JSON'
{
  "messaging_product": "whatsapp",
  "to": "15551234567",
  "type": "template",
  "template": {
    "group_name": "promo group",
    "components": [
      {
        "type": "body",
        "parameters": [
          { "type": "text", "text": "Alice" },
          { "type": "text", "text": "ORD-90211" }
        ]
      }
    ]
  }
}
JSON

Response

Identical to any other send — the standard Meta shape. The body does not reveal which member was picked; correlate delivery via the returned WAMID through status webhooks.

{
  "messaging_product": "whatsapp",
  "contacts": [{ "input": "15551234567", "wa_id": "15551234567" }],
  "messages": [
    { "id": "wamid.HBgLMTU1NTEyMzQ1NjcVAgARGBI...", "message_status": "accepted" }
  ]
}

How a member is picked

At send time SigFollow builds the candidate pool from members that are APPROVED, still attached to the group, and belong to a group whose status is ACTIVE. Candidates are then ordered and one is chosen:

  • Quality first — ordered HIGH > UNKNOWN > MEDIUM > LOW. (UNKNOWN ranks above MEDIUM on purpose: an unknown rating is usually a freshly approved template Meta has not scored yet, and the business preference is to favor new templates over ones already known to be mediocre.)
  • Then oldest-first — ties within the same quality tier are broken by earliest creation time.
  • Then the group's scheduling strategy EARLIEST (default) takes the top-ranked candidate; RANDOM_TOP_N takes the top N and picks one at random. The strategy and N are configured per group in the admin console, not per request.
Delivery outcomes feed quality back
Each send increments the picked member's sent / failure counters, and Meta's delivery + quality webhooks flow back into the same rating that drives selection. Over time the group self-tunes toward its best-performing templates. Candidate lists are cached for ~30 seconds, so a just-added member may take up to half a minute to enter rotation.

Default header media

If the group's templates carry an image header and your request omits the header parameter, SigFollow injects the group's default media automatically (the picked member's archived image, falling back to the group's reference image). You only need to send a header components entry when you want to override it with a per-message image. This mirrors the single-template behavior described in Send recipe #1.

Errors

Group-specific failures surface as a Meta-style error body with code 131000 and type GraphMethodException. The message names the exact reason so you can react programmatically.

Group resolution errors
NameTypeRequiredDescription
Group not found404 · 131000noNo group with that group_nameexists in the API key's tenant. Check the name matches the admin console exactly (case sensitive).
Group not active400 · 131000noThe group exists but is not ACTIVE (it is PAUSED or ARCHIVED). Reactivate it or send with a specific template.name.
WABA mismatch400 · 131000noThe group is bound to a different WhatsApp Business Account than the sending :phoneNumberId. A group can only be used with phone numbers under its own WABA.
No eligible member400 · 131000noThe group has no sendable member right now — every template is unapproved, soft-removed, or otherwise ineligible. Add or approve a member, or fall back to a single template.

Example — group name not found:

{
  "error": {
    "message": "Template group \"promo group\" not found in this tenant",
    "type": "GraphMethodException",
    "code": 131000
  }
}

Standard send errors (401 invalid key, 403 missing scope, 429 rate limit, 131026 outside the 24-hour window) apply exactly as they do for any message send. See the error reference for the full body schema.