smartchat

Create newsletter

Creates a newsletter as a draft with its own template. Nothing is sent: submit the template with create_template_submissions, then call send_newsletter. Needs an idempotency key and returns the newsletter.

POST /v1/newsletters

Permissionnewsletters:write (all permissions)
RiskWrite (no outside effect)
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 classwrite (120 requests per minute per key)
ConfirmationNone
MCP toolsave_newsletter
Since version2026-10-25

#What it does

  • Changes data in your account. It does not send 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).

Body (JSON)

NameTypeRequiredDescription
titlestringyesInternal title. It also names the template. length 1 to 200
textstringyesMessage text, at most 1024 characters. The only placeholder allowed is {{first_name}}. length 1 to 1024
languagestring or nullnoLanguage of the message, for example en or de. Null uses the account language. up to 10 characters
buttonanynoOne button, or null to remove it.
audienceobject or nullnoAudience filter by tags and/or source. Null removes the filter (all contacts with a confirmed opt-in).
audience.tagsarray of stringnoTags, upper or lower case does not matter. The tags must exist on at least one contact. up to 20 items
audience.modestringnoall = contact has every tag. any = contact has at least one tag. none = contact has none of the tags. one of: all, any, none; default "any"
audience.sourcesarray of stringnoWhere the contact came from. up to 8 items

#Examples

curl -X POST "https://api.smartchat.marketing/v1/newsletters" \
  -H "Authorization: Bearer $SMARTCHAT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "title": "Autumn menu",
  "text": "Hi {{first_name}}, our autumn menu is here. Book a table for this week.",
  "audience": {
    "tags": [
      "regular customer"
    ]
  }
}'
import os
import uuid
import requests

response = requests.post(
    "https://api.smartchat.marketing/v1/newsletters",
    headers={
        "Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"],
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "title": "Autumn menu",
        "text": "Hi {{first_name}}, our autumn menu is here. Book a table for this week.",
        "audience": {
            "tags": [
                "regular customer",
            ],
        },
    },
)
response.raise_for_status()
print(response.json())
const response = await fetch("https://api.smartchat.marketing/v1/newsletters", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
    "Idempotency-Key": crypto.randomUUID(),
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "title": "Autumn menu",
    "text": "Hi {{first_name}}, our autumn menu is here. Book a table for this week.",
    "audience": {
      "tags": [
        "regular customer"
      ]
    }
  }),
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());

Response (201):

{
  "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": "draft",
  "ready_to_send": false,
  "not_ready_reason": "template_not_approved",
  "recipients": 412,
  "scheduled_at": null,
  "sent_at": null,
  "created_at": "2026-10-25T09:41:07Z",
  "updated_at": "2026-10-25T09:41:07Z"
}

#Response

Status 201. 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>'.
account_blocked403This account is blocked.
insufficient_scope403This key lacks a required permission.
ip_not_allowed403This IP address is not allowed for this key.
idempotency_in_progress409A request with this idempotency key is still running.
idempotency_key_reused422This idempotency key was already used with a different request.
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.