← All action domains

Campaigns

23 operations. Call each with POST https://app.chirply.io/api/v1/actions/<name> and a bearer token; the response is { "data": { "action", "summary", "result" } }. A read badge means the operation changes nothing; write requires the credential’s write scope.

Archive a broadcast

campaigns.archivewriteconfirm

Archive a campaign so it disappears from the Campaigns list. Its recipients, send ledger and analytics are kept — this is the app's way of removing a campaign; there is no hard delete.

Marked confirm: this operation is irreversible, reaches real people, or spends money. Holding a credential is itself the confirmation for API and MCP callers — call it only when you mean it. The in-app assistant refuses to run it without a human approving first.

Parameters

FieldTypeRequiredDescription
idstring (uuid)requiredThe campaign to archive.

Example

curl -X POST https://app.chirply.io/api/v1/actions/campaigns.archive \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool campaigns_archive at https://app.chirply.io/api/mcp, same bearer token, same input.

Cancel a broadcast

campaigns.cancelwriteconfirm

Halt a campaign for good: every pending and in-flight recipient stops immediately and nothing more goes out. Messages already delivered cannot be recalled, and a canceled campaign cannot be sent again — duplicate it instead.

Marked confirm: this operation is irreversible, reaches real people, or spends money. Holding a credential is itself the confirmation for API and MCP callers — call it only when you mean it. The in-app assistant refuses to run it without a human approving first.

Parameters

FieldTypeRequiredDescription
campaign_idstring (uuid)requiredThe campaign to cancel.

Example

curl -X POST https://app.chirply.io/api/v1/actions/campaigns.cancel \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool campaigns_cancel at https://app.chirply.io/api/mcp, same bearer token, same input.

Create a broadcast

campaigns.createwrite

Create a draft broadcast campaign and seed it with an empty audience, exactly like the New campaign dialog. A campaign sends ONE message ONCE — for a multi-step follow-up sequence with delays between messages, build an automation instead. Nothing is sent here: a draft has to be given content, an audience, and then sent or scheduled.

Parameters

FieldTypeRequiredDescription
namestringrequiredWhat to call it.
channel"email" | "sms" | "whatsapp" | "ringless_voicemail" | "outbound_ivr" | "ai_call"optionalWhat this blast sends. 'whatsapp' is an approved Meta template to policy-eligible opted-in contacts; email/SMS use the org's own providers; the remaining channels place real calls. Nothing is sent until a later send or schedule capability is approved. Default: "email"

Example

curl -X POST https://app.chirply.io/api/v1/actions/campaigns.create \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Example"
  }'
Test with your API key

Over MCP the same operation is the tool campaigns_create at https://app.chirply.io/api/mcp, same bearer token, same input.

Delete a broadcast step

campaigns.delete_stepwriteconfirm

DEPRECATED and no longer possible. A campaign is a one-off broadcast carrying exactly one message, so there are no steps to remove — clear the message with `campaigns.set_message`, or archive the campaign. Multi-step sequences live in automations.

Marked confirm: this operation is irreversible, reaches real people, or spends money. Holding a credential is itself the confirmation for API and MCP callers — call it only when you mean it. The in-app assistant refuses to run it without a human approving first.

Parameters

FieldTypeRequiredDescription
campaign_idstring (uuid)requiredThe campaign the step belonged to.
step_idstring (uuid)requiredThe step to delete. No longer exists.

Example

curl -X POST https://app.chirply.io/api/v1/actions/campaigns.delete_step \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11",
    "step_id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool campaigns_delete_step at https://app.chirply.io/api/mcp, same bearer token, same input.

Duplicate a broadcast

campaigns.duplicatewrite

Copy a campaign — its message, channel, audience, send window and throttle — into a new draft named "<name> (copy)". The copy has no recipients and sends nothing until it is sent or scheduled. This is how a sent campaign is edited: duplicate, then change the copy.

Parameters

FieldTypeRequiredDescription
idstring (uuid)requiredThe campaign to copy.

Example

curl -X POST https://app.chirply.io/api/v1/actions/campaigns.duplicate \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool campaigns_duplicate at https://app.chirply.io/api/mcp, same bearer token, same input.

Enroll contacts in a broadcast

campaigns.enroll_contactswriteconfirm

ENQUEUES REAL MESSAGES. Adds specific contacts to a campaign's recipient list with delivery due immediately, the same as the bulk 'Enroll in campaign' action on the contacts list. If the campaign is sending, they can receive it on the next dispatch tick — real, billed email, SMS, or an approved WhatsApp template. WhatsApp contacts are enrolled only when the selected business number/template is valid and the person has a real initiated thread, durable opt-in, no DNC/suppression, and a policy-valid timezone; eligibility is checked again before the Meta call. Already-enrolled contacts are skipped.

Marked confirm: this operation is irreversible, reaches real people, or spends money. Holding a credential is itself the confirmation for API and MCP callers — call it only when you mean it. The in-app assistant refuses to run it without a human approving first.

Parameters

FieldTypeRequiredDescription
campaign_idstring (uuid)requiredThe campaign to enroll into.
contact_idsarray of (string (uuid))requiredContacts to consider for enrollment. Channel reachability, suppression, DNC, and WhatsApp consent/thread/template/timezone policy can exclude them.

Example

curl -X POST https://app.chirply.io/api/v1/actions/campaigns.enroll_contacts \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11",
    "contact_ids": [
      "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
    ]
  }'
Test with your API key

Over MCP the same operation is the tool campaigns_enroll_contacts at https://app.chirply.io/api/mcp, same bearer token, same input.

Generate copy

campaigns.generate_copyread

Generate or rewrite one email-campaign content block from a plain-language instruction. Returns draft text only; it does not save or send anything. Uses and bills its own OpenRouter account.

Parameters

FieldTypeRequiredDescription
promptstringrequiredWhat the campaign block should say and accomplish.
block_type"heading" | "text" | "button" | "columns"requiredThe email-builder block being written.
currentstringoptionalExisting block copy to rewrite; omit to create copy from scratch.

Example

curl -X POST https://app.chirply.io/api/v1/actions/campaigns.generate_copy \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "example",
    "block_type": "heading"
  }'
Test with your API key

Over MCP the same operation is the tool campaigns_generate_copy at https://app.chirply.io/api/mcp, same bearer token, same input.

Generate image

campaigns.generate_imagewrite

Generate an original campaign image from a prompt, store it in the account's durable R2 asset storage, and return its public URL. Nothing is sent. Uses and bills its own OpenRouter account.

Parameters

FieldTypeRequiredDescription
promptstringrequiredVisual subject and composition; generated images contain no text or logos.
style"photo" | "illustration" | "product" | "abstract"optionalVisual treatment for the generated image. Default: "photo"

Example

curl -X POST https://app.chirply.io/api/v1/actions/campaigns.generate_image \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "example"
  }'
Test with your API key

Over MCP the same operation is the tool campaigns_generate_image at https://app.chirply.io/api/mcp, same bearer token, same input.

Open a broadcast

campaigns.getread

Fetch one campaign with its message, its saved audience spec, and its delivery counts — the whole composer in one payload.

Parameters

FieldTypeRequiredDescription
idstring (uuid)requiredThe campaign's id.

Example

curl -X POST https://app.chirply.io/api/v1/actions/campaigns.get \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool campaigns_get at https://app.chirply.io/api/mcp, same bearer token, same input.

List broadcasts

campaigns.listread

List the organization's broadcast campaigns, newest first, each with its recipient, sent, delivered, opened and clicked counts. A campaign is a one-off blast on a single channel — email, SMS, an approved WhatsApp template, ringless voicemail, outbound IVR or AI call. Archived campaigns are hidden unless asked for, matching the Campaigns page.

Parameters

FieldTypeRequiredDescription
limitintegeroptionalMax rows to return (1–100). Default: 25
offsetintegeroptionalRows to skip. Default: 0
status"draft" | "scheduled" | "sending" | "paused" | "paused_no_funds" | "sent" | … 2 moreoptionalOnly campaigns in this status.
channel"email" | "sms" | "whatsapp" | "ringless_voicemail" | "outbound_ivr" | "ai_call"optionalOnly campaigns sending on this channel.
querystringoptionalText to match in the campaign name.
include_archivedbooleanoptionalInclude archived campaigns, which the app's list hides. Default: false

Example

curl -X POST https://app.chirply.io/api/v1/actions/campaigns.list \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "limit": 25,
    "offset": 0
  }'
Test with your API key

Over MCP the same operation is the tool campaigns_list at https://app.chirply.io/api/mcp, same bearer token, same input.

List broadcast recipients

campaigns.list_recipientsread

The delivery table for a campaign: who is enrolled, which step they are on, when they run next, and why any of them failed, plus the per-status counts the Recipients page shows. Each recipient also carries a `delivery` object — the address the message went to and what happened to it afterwards: sent, delivered, opened and clicked timestamps, and the provider’s error where there was one. That is how to answer “who opened it” or “who bounced” for one person rather than as a campaign total. `delivery` is null for a recipient nothing has been sent to yet, and the engagement timestamps stay null while the provider is not tracking opens or clicks for that sending domain (check with email.tracking_status). Read-only and free.

Parameters

FieldTypeRequiredDescription
limitintegeroptionalMax rows to return (1–100). Default: 25
offsetintegeroptionalRows to skip. Default: 0
campaign_idstring (uuid)requiredThe campaign whose recipients to list.
status"pending" | "active" | "completed" | "unsubscribed" | "bounced" | "failed" | … 1 moreoptionalOnly recipients in this status.

Example

curl -X POST https://app.chirply.io/api/v1/actions/campaigns.list_recipients \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool campaigns_list_recipients at https://app.chirply.io/api/mcp, same bearer token, same input.

Pause a sending broadcast

campaigns.pausewrite

Stop a campaign that is mid-blast. Recipients already sent to keep their messages; everyone still queued stays queued until it is resumed. Only a campaign in 'sending' can be paused.

Parameters

FieldTypeRequiredDescription
campaign_idstring (uuid)requiredThe campaign to pause.

Example

curl -X POST https://app.chirply.io/api/v1/actions/campaigns.pause \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool campaigns_pause at https://app.chirply.io/api/mcp, same bearer token, same input.

Preview the audience count

campaigns.preview_audienceread

Count how many contacts a campaign would actually reach — channel-reachable and not suppressed — without saving or sending anything. Defaults to the campaign's saved audience; any field you pass overrides that field for the preview only.

Parameters

FieldTypeRequiredDescription
campaign_idstring (uuid)requiredThe campaign to preview.
channel"email" | "sms" | "whatsapp" | "ringless_voicemail" | "outbound_ivr" | "ai_call"optionalOverride the channel. Defaults to the campaign's own channel. WhatsApp preview additionally requires a saved approved template and counts only real initiated threads with durable opt-in, no DNC/suppression, and a policy-valid timezone.
tag_idsarray of (string (uuid))optionalOverride the tag filter.
lifecyclestring (or null)optionalOverride the lifecycle filter.
searchstring (or null)optionalOverride the text search.
manual_contact_idsarray of (string (uuid))optionalOverride the explicit contact list.
list_idsarray of (string (uuid))optionalOverride included static list ids.
segment_idsarray of (string (uuid))optionalOverride included Smart Segment ids.
exclude_list_idsarray of (string (uuid))optionalOverride excluded static list ids.
exclude_segment_idsarray of (string (uuid))optionalOverride excluded Smart Segment ids.
exclude_unsubscribedbooleanoptionalOverride whether suppressed contacts are dropped.

Example

curl -X POST https://app.chirply.io/api/v1/actions/campaigns.preview_audience \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool campaigns_preview_audience at https://app.chirply.io/api/mcp, same bearer token, same input.

Preview combined message

campaigns.preview_voicewriteconfirm

Hear what a ringless-voicemail or outbound-IVR broadcast will actually sound like: the personalized spoken introduction, rendered with real ElevenLabs speech, followed by the pause and the prerecorded audio the contact hears next. COSTS MONEY — each preview is a real text-to-speech render on its OWN ElevenLabs account and spends a small number of its credits, so don't call it in a loop. Nothing is saved to the campaign, and no call, voicemail or message reaches anybody. Returns the spoken introduction as inline base64 MP3 (roughly 100–500 KB — pass include_audio=false if you only need to confirm the render worked and read back what will be spoken), plus a short-lived playback link for the recorded tail.

Marked confirm: this operation is irreversible, reaches real people, or spends money. Holding a credential is itself the confirmation for API and MCP callers — call it only when you mean it. The in-app assistant refuses to run it without a human approving first.

Parameters

FieldTypeRequiredDescription
campaign_idstring (uuid)optionalPreview this saved campaign — its message body, ElevenLabs voice, recorded tail and pause are used unless overridden below. Omit it to preview text that hasn't been saved to a campaign yet, in which case `text` is required.
textstringoptionalThe personalized introduction to speak, up to 500 characters (the same cap the button uses). Merge tokens like {{first_name}} are filled in before speaking. Defaults to the campaign's saved message body.
contact_idstring (uuid)optionalFill merge tokens from this real contact, to hear exactly what they will hear. Omit to use sample values ('John', 'Acme Company'), which is what the button in the app does.
voice_idstringoptionalElevenLabs voice id to speak the introduction. Defaults to the campaign's saved voice, then the account's default ElevenLabs voice.
audio_asset_idstring (uuid)optionalThe saved recording that plays after the introduction. Defaults to the campaign's own. Its playback link is returned; the recording itself is not re-rendered and costs nothing.
pause_secondsintegeroptionalWhole seconds of silence between the spoken introduction and the recording. Defaults to the campaign's saved pause, or 0.
include_audiobooleanoptionalTrue (default) returns the rendered introduction inline as base64 MP3 so it can be played. False renders it anyway — the ElevenLabs credits are spent either way — but returns only the byte count, which keeps a large payload out of a conversation when you just want to check it works. Default: true

Example

curl -X POST https://app.chirply.io/api/v1/actions/campaigns.preview_voice \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11",
    "text": "example"
  }'
Test with your API key

Over MCP the same operation is the tool campaigns_preview_voice at https://app.chirply.io/api/mcp, same bearer token, same input.

Resume a paused broadcast

campaigns.resumewriteconfirm

RESTARTS A REAL BLAST. Puts a paused campaign back into 'sending' so the dispatcher immediately continues delivering to every recipient still queued — real, billed emails, texts, or Meta-approved WhatsApp templates. WhatsApp consent, DNC/suppression, template approval, timezone, and local-window eligibility are checked again before each provider call, but Meta can bill every template it accepts. Only a paused campaign (including one paused for lack of funds) can be resumed.

Marked confirm: this operation is irreversible, reaches real people, or spends money. Holding a credential is itself the confirmation for API and MCP callers — call it only when you mean it. The in-app assistant refuses to run it without a human approving first.

Parameters

FieldTypeRequiredDescription
campaign_idstring (uuid)requiredThe campaign to resume.

Example

curl -X POST https://app.chirply.io/api/v1/actions/campaigns.resume \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool campaigns_resume at https://app.chirply.io/api/mcp, same bearer token, same input.

Save broadcast content (deprecated)

campaigns.save_stepwrite

DEPRECATED — use `campaigns.set_message`. Campaigns are one-off broadcasts now: they carry a single message, so there are no steps to order. This still writes that message, and ignores step_id, delay_amount and delay_unit. For a multi-step sequence with delays, build an automation.

Parameters

FieldTypeRequiredDescription
campaign_idstring (uuid)requiredThe campaign this content belongs to.
step_idstring (uuid)optionalIgnored — a campaign has one message.
channel"email" | "sms" | "whatsapp" | "ringless_voicemail" | "outbound_ivr" | "ai_call"optionalWhat this blast sends. Default: "email"
bodystringrequiredThe message body. Supports {{merge}} tokens.
subjectstring (or null)optionalEmail subject line. Email only.
from_number_idstring (uuid) (or null)optionalPhone number id this blast sends or dials from.
from_emailstring (or null)optionalFrom address override for email.
delay_amountintegeroptionalIgnored — broadcasts send once.
delay_unitstringoptionalIgnored — broadcasts send once.

Example

curl -X POST https://app.chirply.io/api/v1/actions/campaigns.save_step \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11",
    "body": "example"
  }'
Test with your API key

Over MCP the same operation is the tool campaigns_save_step at https://app.chirply.io/api/mcp, same bearer token, same input.

Schedule the broadcast

campaigns.schedulewriteconfirm

COMMITS A REAL SEND at a future time. Snapshots the eligible audience now and sets the start time; when it arrives the dispatcher contacts every recipient through the org's OWN Mailgun, Twilio, or connected Meta WhatsApp account — potentially thousands of billed emails, texts, approved WhatsApp templates, voicemail drops, or phone calls, unattended. WhatsApp requires a currently approved template plus a real customer-initiated thread, durable opt-in, no DNC/suppression, and a policy-valid recipient timezone; eligibility is checked again before each provider call and Meta can bill each accepted template. Use campaigns.cancel before the start time to stop queued work. Requires saved content, a non-empty eligible audience, and a future time.

Marked confirm: this operation is irreversible, reaches real people, or spends money. Holding a credential is itself the confirmation for API and MCP callers — call it only when you mean it. The in-app assistant refuses to run it without a human approving first.

Parameters

FieldTypeRequiredDescription
campaign_idstring (uuid)requiredThe campaign to schedule.
scheduled_atstring (date-time)requiredWhen sending starts, as an ISO 8601 timestamp with offset.

Example

curl -X POST https://app.chirply.io/api/v1/actions/campaigns.schedule \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11",
    "scheduled_at": "2026-09-17T15:00:00Z"
  }'
Test with your API key

Over MCP the same operation is the tool campaigns_schedule at https://app.chirply.io/api/mcp, same bearer token, same input.

Send the broadcast now

campaigns.send_nowwriteconfirm

SENDS FOR REAL, IMMEDIATELY, to real people. Resolves the saved audience and starts delivering through the org's OWN Mailgun, Twilio, or connected Meta WhatsApp account — potentially thousands of billed emails, texts, approved WhatsApp templates, voicemail drops, or phone calls. WhatsApp enrolls only real customer-initiated threads with durable opt-in, no DNC/suppression, a currently approved template language, and a policy-valid recipient timezone; Meta can bill every accepted template. Voice channels place actual outbound calls. There is no undo; campaigns.pause/cancel can stop only work not already accepted. Campaign-engine channels send a bounded first wave inline and queue the rest; voicemail/call channels use their paced dispatchers. Requires saved content and a non-empty eligible audience, and refuses a campaign that already sent.

Marked confirm: this operation is irreversible, reaches real people, or spends money. Holding a credential is itself the confirmation for API and MCP callers — call it only when you mean it. The in-app assistant refuses to run it without a human approving first.

Parameters

FieldTypeRequiredDescription
campaign_idstring (uuid)requiredThe campaign to blast now.

Example

curl -X POST https://app.chirply.io/api/v1/actions/campaigns.send_now \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool campaigns_send_now at https://app.chirply.io/api/mcp, same bearer token, same input.

Choose the audience

campaigns.set_audiencewrite

Replace a campaign's audience spec — who it will go to. The spec is resolved to actual contacts only at send/schedule time, so this write sends nothing. Supplying manual_contact_ids overrides the tag/lifecycle/search filters entirely. Use campaigns.preview_audience to see how many people it matches first.

Parameters

FieldTypeRequiredDescription
campaign_idstring (uuid)requiredThe campaign whose audience to set.
tag_idsarray of (string (uuid))optionalContacts carrying any of these tags. Default: []
lifecyclestring (or null)optionalOnly contacts at this lifecycle stage (lead, trial, active, customer, churned). Default: null
searchstring (or null)optionalFree-text match across name, business, email and phone. Default: null
manual_contact_idsarray of (string (uuid))optionalAn explicit contact list. When non-empty, the filters above are ignored. Default: []
list_idsarray of (string (uuid))optionalInclude contacts who currently belong to any of these lists. Default: []
segment_idsarray of (string (uuid))optionalInclude contacts who currently match any of these saved smart segments. Default: []
exclude_list_idsarray of (string (uuid))optionalExclude contacts who currently belong to any of these lists. Default: []
exclude_segment_idsarray of (string (uuid))optionalExclude contacts who currently match any of these saved smart segments. Default: []
exclude_unsubscribedbooleanoptionalDrop anyone on the org's suppression list for the channel. Leave true. Default: true

Example

curl -X POST https://app.chirply.io/api/v1/actions/campaigns.set_audience \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool campaigns_set_audience at https://app.chirply.io/api/mcp, same bearer token, same input.

Save broadcast content

campaigns.set_messagewrite

Write the one message this broadcast sends, and pick which channel it goes out on. Nothing is sent by saving — this only stores the content. Only draft or paused campaigns can be edited. A campaign sends a single message; for a multi-step sequence with delays, build an automation instead.

Parameters

FieldTypeRequiredDescription
campaign_idstring (uuid)requiredThe campaign this content belongs to.
channel"email" | "sms" | "whatsapp" | "ringless_voicemail" | "outbound_ivr" | "ai_call"optionalWhat to send. 'email' uses the org's Mailgun; 'sms' uses Twilio; 'whatsapp' sends a currently approved Meta template only to policy-eligible opted-in contacts; the remaining channels place real calls through the org's telephony providers. Default: "email"
bodystringoptionalThe message body: email copy, SMS text, outbound-IVR script, or the personalized introduction for a hybrid ringless voicemail. PLAIN TEXT, not HTML — raw tags are escaped and arrive as visible characters. Blank lines start new paragraphs, and `[the words you see](https://where-they-go)` becomes an inline hyperlink (https, http, mailto, tel or a {{merge}} token; anything else stays literal text). Supports {{merge}} tokens. For WhatsApp this is display-only and never authorizes delivery; the approved template fields are authoritative. Ignored for ai_call, where the agent scripts the call. Default: ""
subjectstring (or null)optionalEmail subject line. Email only.
from_number_idstring (uuid) (or null)optionalTwilio phone-number row id this blast sends or dials from. Used by SMS and voice channels; WhatsApp uses phone_number_id instead.
from_emailstring (or null)optionalFrom address override for email. null clears it back to the org default. Ignored when the blast sends through an email pool.
email_identity_idstring (uuid) (or null)optionalEmail only: the account email identity this blast sends from. null clears it back to the account default. Setting this clears any email pool.
email_pool_idstring (uuid) (or null)optionalEmail only: send through an email pool instead — each recipient's message rotates across the pool's member addresses, honoring their warmup allowances, and replies go to the pool's reply-to. Setting this clears any single identity. null clears the pool.
include_signaturebooleanoptionalEmail only: append the sender's email signature above the unsubscribe footer. Defaults to false — a broadcast already ends in a compliance footer. Uses whichever signature would sign the campaign author's one-to-one email.
phone_number_idstringoptionalWhatsApp only: Meta's connected business phone-number id. Use meta.whatsapp_accounts_list to choose one that is subscribed to Chirply webhooks.
template_namestringoptionalWhatsApp only: exact name of a currently approved Meta template. Use meta.whatsapp_templates_list; approval is checked again before enrollment and each real send.
template_languagestringoptionalWhatsApp only: exact approved language code for template_name, such as en_US. Languages are independently approved by Meta.
template_componentsobject[]optionalWhatsApp only: parameters for the approved template's header, body, and dynamic buttons. Every required text, HTTPS media link, payload, or coupon value must be supplied; {{merge_fields}} inside string values render per recipient.
audio_asset_idstring (uuid)optionalRingless voicemail only: the saved recording contacts hear. Required before an RVM broadcast can send.
filter_number_idstring (uuid)optionalRingless voicemail only: the second number that seizes the line. A voicemail drop needs two DIFFERENT active numbers. Omit to pick one automatically.
menu_idstring (uuid)optionalOutbound IVR only: the IVR menu to play, so the contact can press a key and be routed. Omit to just read the body aloud and hang up.
message_mode"tts" | "recording" | "hybrid"optionalOutbound voice without a menu: 'tts' speaks the body only; ringless voicemail: 'recording' plays audio_asset_id only; 'hybrid' speaks the merge-personalized body and then plays the selected recording.
hybrid_audio_asset_idstring (uuid)optionalOutbound hybrid voice only: reusable prerecorded audio asset played after the personalized introduction.
hybrid_pause_secondsintegeroptionalOutbound hybrid voice only: whole-second pause between the intro and recording.
intro_tts_provider"twilio" | "elevenlabs"optionalHybrid outbound IVR or ringless voicemail: Twilio speaks each merged intro live, or ElevenLabs pre-renders it per recipient using the account's credits.
intro_tts_voice_idstringoptionalElevenLabs voice id used for each personalized introduction.
tts_voicestringoptionalTwilio voice used for the introduction when intro_tts_provider is twilio.
agent_idstring (uuid)optionalAI call only: the AI voice agent that takes the call. Required for ai_call.
goalstringoptionalAI call only: what the agent should achieve on this call, overriding its standing goal.

Example

curl -X POST https://app.chirply.io/api/v1/actions/campaigns.set_message \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool campaigns_set_message at https://app.chirply.io/api/mcp, same bearer token, same input.

Save the sending window

campaigns.set_schedulewrite

Set a campaign's timezone, quiet-hours window, allowed weekdays and per-minute throttle. This governs WHEN queued messages go out; it does not start a send. Replaces the whole schedule — omitted fields fall back to their defaults, matching the Schedule tab.

Parameters

FieldTypeRequiredDescription
campaign_idstring (uuid)requiredThe campaign to configure.
timezonestringoptionalIANA timezone used when a recipient has none of their own. Default: "UTC"
respect_windowbooleanoptionalHold sends outside the window/days below instead of going out immediately. Default: false
window_startstring (or null)optionalEarliest local send time, HH:MM. null means no lower bound. Default: null
window_endstring (or null)optionalLatest local send time, HH:MM. null means no upper bound. Default: null
window_daysarray of ("Mon" | "Tue" | "Wed" | "Thu" | "Fri" | "Sat" | … 1 more)optionalWeekdays sending is allowed. Empty means all seven. Default: []
throttle_per_mininteger (or null)optionalCap on messages per minute. null sends as fast as the dispatcher can. Default: null
send_windowsobject[]optionalIndependent local-time delivery windows. Empty uses the legacy single window fields. Default: []
send_windows[].idstringrequiredStable id for this window.
send_windows[].startstringrequiredLocal opening time in HH:MM.
send_windows[].endstringrequiredLocal closing time in HH:MM.
send_windows[].daysarray of ("Mon" | "Tue" | "Wed" | "Thu" | "Fri" | "Sat" | … 1 more)requiredWeekdays this window is active.
throttle_mode"fixed" | "random"optionalFixed uses each maximum; random chooses a fresh target within each minimum/maximum range. Default: "fixed"
throttle_min_per_mininteger (or null)optionalMinimum messages per minute for random pacing. Default: null
throttle_max_per_mininteger (or null)optionalMaximum messages per minute; null disables this interval. Default: null
throttle_min_per_hourinteger (or null)optionalMinimum messages per hour for random pacing. Default: null
throttle_max_per_hourinteger (or null)optionalMaximum messages per hour; null disables this interval. Default: null
throttle_min_per_dayinteger (or null)optionalMinimum messages per rolling 24 hours for random pacing. Default: null
throttle_max_per_dayinteger (or null)optionalMaximum messages per rolling 24 hours; null disables this interval. Default: null

Example

curl -X POST https://app.chirply.io/api/v1/actions/campaigns.set_schedule \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool campaigns_set_schedule at https://app.chirply.io/api/mcp, same bearer token, same input.

Broadcast analytics

campaigns.statsread

The channel-aware delivery funnel for one campaign — recipients, sent and delivered, plus email opens/clicks or WhatsApp reads where supported, and bounced, failed and unsubscribed outcomes — computed from the send ledger exactly as the Analytics page renders it.

Parameters

FieldTypeRequiredDescription
campaign_idstring (uuid)requiredThe campaign to report on.

Example

curl -X POST https://app.chirply.io/api/v1/actions/campaigns.stats \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool campaigns_stats at https://app.chirply.io/api/mcp, same bearer token, same input.

Edit broadcast details

campaigns.updatewrite

Rename a campaign or change its sender overrides (the From email address, or the phone number SMS steps send from). Omitted fields are left alone. Content, audience and schedule have their own capabilities.

Parameters

FieldTypeRequiredDescription
idstring (uuid)requiredThe campaign to edit.
namestringoptionalNew name.
from_emailstring (or null)optionalFrom address for email steps. null clears it back to the org default.
from_number_idstring (uuid) (or null)optionalPhone number id SMS steps send from. null clears it.

Example

curl -X POST https://app.chirply.io/api/v1/actions/campaigns.update \
  -H "Authorization: Bearer chp_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "2f6a1c1e-6c3b-4c62-9f6e-8a2d4b7c9e11"
  }'
Test with your API key

Over MCP the same operation is the tool campaigns_update at https://app.chirply.io/api/mcp, same bearer token, same input.

The machine-readable version of this page is GET https://app.chirply.io/api/v1/actions?domain=campaigns — same operations, with full JSON Schemas. Authentication, errors and rate limits are covered in the API documentation home.