niiko/developers

Miira · leads y WhatsApp v1 vigente

miira.broadcast_quoted

Presupuesta mandar el MISMO mensaje de WhatsApp a varios clientes dichos por su nombre (hasta 50). NO envía nada: dice, por cliente, si le llega el texto tal cual (ventana de 24 h abierta, gratis), si hace falta una plantilla aprobada y cuánto cuesta, o por qué no se le puede escribir. Devuelve un presupuesto firmado que vale 15 minutos; para enviar, llama a miira.broadcast_sent con él. Enséñale el presupuesto a la persona antes. `purpose` opcional: `notice` (por omisión) es el aviso de siempre; `promotion` NUNCA manda texto libre, ni con la ventana abierta, y exige una plantilla aprobada de MARKETING (si no, plantilla_invalida): solo llega a quien dio su consentimiento de marketing (si no, no_marketing_consent) y deja fuera los números de EE. UU. (us_moratorium). En una promoción `message` no se envía nunca: sale la plantilla con sus `templateValues`. Usa `promotion` para ofertas y campañas, nunca para una respuesta ni un aviso.

Última actualización

POST /api/v1/actions/miira.broadcast_quoted
Alcance de la llave
miira.broadcast_quoted@1
Permiso del workspace
api.miira.broadcast_quoted apagado por defecto
Dos permisos, no uno

Hacen falta las dos cosas: una llave con ese alcance, y que el dueño del workspace haya encendido el permiso. Tener la llave no basta — son dos decisiones de personas distintas.

Petición

campotiporeglas
clientsstring[]obligatorio
messagestringobligatoriomin 1 · max 4096
templatestringopcionalmin 1 · max 512
templateValuesstring[]opcional
purpose"notice" | "promotion"opcional

Respuesta — output cuando status es done

campotiporeglas
rowsobject[]obligatorio
totalsobjectobligatorio
quotestring | nullobligatorio
expiresAtstring | nullobligatorio

rows[]

campotiporeglas
clientstringobligatorio
clientIdstring | nullobligatorio
clientNamestring | nullobligatorio
outcome"free_text" | "template" | "needs_template" | "no_phone" | "suppressed" | "consent_revoked" | "no_marketing_consent" | "quiet_hours" | "not_found" | "ambiguous" | "too_many" | "us_moratorium"obligatorio
costUsdstring | nullobligatorio
candidatesstring[]opcional

totals

campotiporeglas
freeTextintegerobligatorio
templateintegerobligatorio
skippedintegerobligatorio
costUsdstringobligatorio

Ejemplo

# One request, one idempotency key: retrying with the same key never runs twice.
curl -X POST https://niiko.org/api/v1/actions/miira.broadcast_quoted \
  -H "Authorization: Bearer nk_…" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "clients": [
      "…"
    ],
    "message": "…"
  }'
# 200 → done · 202 → pending_approval (a person signs later) · 4xx → refused, with a named reason

Por qué puede negarse

Cada motivo dice quién puede arreglarlo y cómo. Con motivo stale, detail.message dice qué hacer.

plantilla_invalidatarifas_vencidassin_permiso

En los clientes

@vorluno/niiko-sdkniiko.quotedBroadcast()
niiko (Python)niiko.quoted_broadcast()
niiko-cliniiko run miira.broadcast_quoted
n8n-nodes-niikomiiraBroadcastQuoted
niiko-mcp-servermiira_broadcast_quoted

Historial