smartchat

Preview newsletter send

Calculates who would receive a newsletter, now or at a given time, and whether sending would be accepted. Nothing is sent and nothing is saved. Use it before send_newsletter.

GET /v1/newsletters/{newsletter_id}/send-preview

Permissionnewsletters:read (all permissions)
RiskRead
Idempotency-KeyNot needed (how it works)
Safe to repeatSafe: the call only reads.
Rate limit classread (120 requests per minute per key)
ConfirmationNone
MCP toolplan_newsletter_send
Since version2026-10-25

#What it does

  • Only reads data. It changes nothing and sends nothing.

#Request

Path parameters

NameTypeDescription
newsletter_idstringID of the newsletter, from list_newsletters.

Query parameters

NameTypeRequiredDescription
whenstringno'now' or a time in ISO 8601, for example 2026-11-03T10:00:00+01:00. A time without a zone counts as Zurich time. length 3 to 40; default "now"

#Examples

curl "https://api.smartchat.marketing/v1/newsletters/nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b/send-preview?when=now" \
  -H "Authorization: Bearer $SMARTCHAT_API_KEY"
import os
import requests

response = requests.get(
    "https://api.smartchat.marketing/v1/newsletters/nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b/send-preview",
    headers={"Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"]},
    params={
        "when": "now",
    },
)
response.raise_for_status()
print(response.json())
const response = await fetch("https://api.smartchat.marketing/v1/newsletters/nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b/send-preview?when=now", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
  },
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());

Response (200):

{
  "object": "newsletter_send_preview",
  "newsletter_id": "nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b",
  "when": "now",
  "can_send": true,
  "blocked_by": [],
  "recipients": 412,
  "audience_total": 938,
  "excluded": {
    "opted_out": 12,
    "not_confirmed": 30,
    "suppressed": 2,
    "no_phone": 3,
    "outside_audience": 524
  },
  "estimated_days": 1,
  "daily_limit": 1000,
  "text": "Hi {{first_name}}, our autumn menu is here. Book a table for this week."
}

#Response

Status 200. Every response has the headers Request-Id, SmartChat-Version and X-RateLimit-*.

NameTypeDescription
objectstringAlways "newsletter_send_preview". always newsletter_send_preview
newsletter_idstringNewsletter ID.
whenstring'now' or the time you asked for. up to 40 characters
can_sendbooleanTrue if send_newsletter would be accepted now.
blocked_byarray of objectWhy send_newsletter would be refused. Empty if it would be accepted. up to 10 items
blocked_by[].codestringError code from the error catalog. up to 60 characters
blocked_by[].messagestringEnglish explanation. up to 500 characters
recipientsintegerContacts that would receive the newsletter: confirmed opt-in, not unsubscribed, not on the stop list, inside the audience filter. 0 to 100000000
audience_totalintegerContacts with a confirmed opt-in and a phone number, before the audience filter. Always recipients + excluded.suppressed + excluded.outside_audience. 0 to 100000000
excludedobjectContacts of the whole account that are left out, by reason. All counters come from the same evaluation.
excluded.opted_outintegerContacts who unsubscribed. They never receive a newsletter. 0 to 100000000
excluded.not_confirmedintegerContacts without a confirmed opt-in. 0 to 100000000
excluded.suppressedintegerConfirmed contacts whose number is on the stop list (they wrote STOP). They never receive a newsletter. 0 to 100000000
excluded.no_phoneintegerContacts without a phone number. They cannot receive a newsletter. 0 to 100000000
excluded.outside_audienceintegerConfirmed contacts that the audience filter leaves out. 0 to 100000000
estimated_daysintegerHow many days the send takes because of the daily limit of the WhatsApp number. 0 if nobody receives it. 0 to 10000
daily_limitinteger or nullDaily limit of the WhatsApp number, or null if unlimited. 0 to 100000000
textstringThe message text that goes out (not personalised). up to 20000 characters

#Errors

CodeStatusWhen
api_key_expired401This API key has expired.
api_key_invalid401This API key is not valid.
api_key_revoked401This API key was revoked.
authentication_required401No API key was sent. Send 'Authorization: Bearer <key>'.
account_blocked403This account is blocked.
insufficient_scope403This key lacks a required permission.
ip_not_allowed403This IP address is not allowed for this key.
newsletter_not_found404No newsletter with this ID exists in this account.
validation_failed422A field is not valid.
rate_limited429Too many requests. Wait and try again.
internal_error500Something went wrong on our side.
service_unavailable503The service is temporarily unavailable.

All errors use one format.