smartchat

Control newsletter send

Cancels a scheduled newsletter, pauses a running one or resumes a paused or failed one. Messages already delivered stay delivered, and resuming reaches only contacts who did not get it yet. Needs an idempotency key.

POST /v1/newsletters/{newsletter_id}/control

Permissionnewsletters:send (all permissions)
RiskSend (reaches other people)
Idempotency-KeyRequired (how it works)
Safe to repeatSafe to repeat with the same Idempotency-Key: the first answer comes back and nothing is done twice.
Rate limit classsend (120 requests per minute per key)
ConfirmationNone
MCP toolcontrol_newsletter
Since version2026-10-25

#What it does

  • Sends WhatsApp messages to contacts.
  • Safe to repeat with the same Idempotency-Key.

#Request

Header

NameRequiredDescription
AuthorizationyesBearer <key>
Idempotency-KeyyesA unique value for this operation, for example a UUID (1 to 255 visible ASCII characters).

Path parameters

NameTypeDescription
newsletter_idstringID of the newsletter, from list_newsletters.

Body (JSON)

NameTypeRequiredDescription
actionstringyescancel = a scheduled newsletter goes back to draft. pause = stop a running send. resume = continue a paused or failed send. one of: cancel, pause, resume

#Examples

curl -X POST "https://api.smartchat.marketing/v1/newsletters/nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b/control" \
  -H "Authorization: Bearer $SMARTCHAT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "action": "cancel"
}'
import os
import uuid
import requests

response = requests.post(
    "https://api.smartchat.marketing/v1/newsletters/nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b/control",
    headers={
        "Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"],
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "action": "cancel",
    },
)
response.raise_for_status()
print(response.json())
const response = await fetch("https://api.smartchat.marketing/v1/newsletters/nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b/control", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
    "Idempotency-Key": crypto.randomUUID(),
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "action": "cancel"
  }),
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());

Response (200):

{
  "object": "newsletter",
  "id": "nwl_3c9e1f7a5b2d4e8f9a0b1c2d3e4f5a6b",
  "title": "Autumn menu",
  "text": "Hi {{first_name}}, our autumn menu is here. Book a table for this week.",
  "language": "en",
  "button": {
    "type": "url",
    "text": "See the menu",
    "url": "https://example.com/menu"
  },
  "audience": {
    "tags": [
      "regular customer"
    ],
    "mode": "any",
    "sources": []
  },
  "status": "draft",
  "template_id": "tpl_0f8c1a2e4b7d4c3e9a5b6d7e8f901234",
  "template_status": "approved",
  "ready_to_send": true,
  "not_ready_reason": null,
  "recipients": 412,
  "scheduled_at": null,
  "sent_at": null,
  "created_at": "2026-10-25T09:41:07Z",
  "updated_at": "2026-10-25T09:41:07Z"
}

#Response

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

NameTypeDescription
objectstringAlways "newsletter". always newsletter
idstringNewsletter ID.
titlestringInternal title and name of the template. up to 200 characters
textstringMessage text of the newsletter. up to 20000 characters
languagestring or nullLanguage of the message, or null for the account language. up to 10 characters
buttonanyButton of the newsletter or null.
audienceobject or nullAudience filter. Null means all contacts with a confirmed opt-in.
audience.tagsarray of stringTags used for the filter (lower case). up to 100 items
audience.modestringall = contact has every tag. any = contact has at least one tag. none = contact has none of the tags. one of: all, any, none
audience.sourcesarray of stringWhere the contact came from. A contact matches if a tag OR a source matches. up to 20 items
statusstringState of the newsletter. one of: draft, scheduled, sending, paused, completed, canceled, failed
template_idstring or nullID of the template that carries this newsletter. Submit it with create_template_submissions. up to 36 characters
template_statusstring or nullApproval state of that template. A newsletter can only be sent when it is approved. one of: draft, pending, approved, rejected, paused, disabled, null
ready_to_sendbooleanTrue if send_newsletter would be accepted now (draft or scheduled, with text, approved template and a connected number).
not_ready_reasonstring or nullWhy it cannot be sent yet, otherwise null. one of: no_text, template_not_approved, no_number, locked, null; up to 60 characters
recipientsintegerNumber of contacts that receive it (planned for drafts, actual for started newsletters). 0 to 100000000
scheduled_atstring or nullWhen the send is scheduled, otherwise null. up to 40 characters; format date-time
sent_atstring or nullWhen the send finished, otherwise null. up to 40 characters; format date-time
created_atstringWhen the newsletter was created. up to 40 characters; format date-time
updated_atstringWhen the newsletter was last changed. up to 40 characters; format date-time

#Errors

CodeStatusWhen
bad_request400The request could not be read.
idempotency_key_invalid400The 'Idempotency-Key' header must be 1 to 255 visible ASCII characters.
idempotency_key_required400This call needs an 'Idempotency-Key' header.
missing_parameter400A required field is missing.
unknown_parameter400A field is not known.
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>'.
insufficient_credits402The credits are not enough.
quota_exceeded402The monthly message quota is used up.
account_blocked403This account is blocked.
insufficient_scope403This key lacks a required permission.
ip_not_allowed403This IP address is not allowed for this key.
subscription_locked403The subscription or payment state blocks this function.
newsletter_not_found404No newsletter with this ID exists in this account.
conflict409The state of the object does not allow this.
idempotency_in_progress409A request with this idempotency key is still running.
newsletter_locked409The newsletter is scheduled or sent and cannot be changed.
audience_empty422The audience has no reachable contacts.
idempotency_key_reused422This idempotency key was already used with a different request.
template_not_approved422The template is not approved.
template_rejected422WhatsApp rejected the template.
validation_failed422A field is not valid.
whatsapp_not_connected422No WhatsApp number is connected.
rate_limited429Too many requests. Wait and try again.
internal_error500Something went wrong on our side.
upstream_error502A connected service (for example WhatsApp) reported an error.
service_unavailable503The service is temporarily unavailable.
suppression_check_unavailable503The suppression list cannot be read, so nothing was sent.

All errors use one format.