{"openapi":"3.0.0","paths":{"/api/v1/campaigns/segments":{"post":{"operationId":"CampaignSegmentsController_create","summary":"Create a segment","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCampaignSegmentDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignSegmentCreatedDto"}}}}},"tags":["Segments"],"security":[{"bearer":[]}],"description":"name is required, up to 200 characters. description is optional, up to 2000 characters. Returns the segment id used when creating a campaign."},"get":{"operationId":"CampaignSegmentsController_list","summary":"List segments","parameters":[{"name":"limit","required":false,"in":"query","description":"Page size. Defaults to 50, maximum 100.","schema":{"type":"string"}},{"name":"cursor","required":false,"in":"query","description":"nextCursor from the previous page. Leave empty for the first page.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignSegmentPageDto"}}}}},"tags":["Segments"],"security":[{"bearer":[]}],"description":"Newest first. limit is the page size, default 50, maximum 100. cursor is the nextCursor from the previous page. Leave cursor empty for the first page."}},"/api/v1/campaigns/segments/{segmentId}/members":{"get":{"operationId":"CampaignSegmentsController_listMembers","summary":"List segment members","parameters":[{"name":"segmentId","required":true,"in":"path","schema":{"type":"string"},"description":"Segment id returned by create or list."},{"name":"limit","required":false,"in":"query","description":"Page size. Defaults to 50, maximum 100.","schema":{"type":"string"}},{"name":"cursor","required":false,"in":"query","description":"nextCursor from the previous page. Leave empty for the first page.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignSegmentMemberPageDto"}}}}},"tags":["Segments"],"security":[{"bearer":[]}],"description":"limit is the page size, default 50, maximum 100. cursor is the nextCursor from the previous page."},"post":{"operationId":"CampaignSegmentsController_addMembers","summary":"Add segment members","description":"members is a non-empty list. Each item needs name. phone is E.164 or omitted. bsuid is the provider id, for example ab.abc123xyz, or omitted. One of phone or bsuid is required. A duplicate phone or BSUID in the segment is rejected. The segment cannot exceed 500 members. Each member may include attributes — a flat JSON object of string key-value pairs (max 50 keys, key up to 64 chars matching [a-zA-Z_][a-zA-Z0-9_]*, value up to 1024 chars, total JSON up to 10KB). Attributes are used for per-recipient template variable bindings.","parameters":[{"name":"segmentId","required":true,"in":"path","schema":{"type":"string"},"description":"Segment id returned by create or list."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddCampaignSegmentMembersDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignSegmentMemberBatchDto"}}}}},"tags":["Segments"],"security":[{"bearer":[]}]},"put":{"operationId":"CampaignSegmentsController_replaceMembers","summary":"Replace segment members","description":"Deletes every current member and inserts this list. The same name, phone, and bsuid rules apply as when adding members. The new list cannot exceed 500 members.","parameters":[{"name":"segmentId","required":true,"in":"path","schema":{"type":"string"},"description":"Segment id returned by create or list."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplaceCampaignSegmentMembersDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignSegmentMemberBatchDto"}}}}},"tags":["Segments"],"security":[{"bearer":[]}]},"delete":{"operationId":"CampaignSegmentsController_removeMembers","summary":"Remove segment members","parameters":[{"name":"segmentId","required":true,"in":"path","schema":{"type":"string"},"description":"Segment id returned by create or list."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveCampaignSegmentMembersDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignSegmentMembersRemovedDto"}}}}},"tags":["Segments"],"security":[{"bearer":[]}],"description":"memberIds is a non-empty list of member ids from the member list. Other members stay."}},"/api/v1/campaigns/segments/{segmentId}/members/{memberId}":{"patch":{"operationId":"CampaignSegmentsController_patchMember","summary":"Update one segment member","parameters":[{"name":"segmentId","required":true,"in":"path","schema":{"type":"string"},"description":"Segment id returned by create or list."},{"name":"memberId","required":true,"in":"path","schema":{"type":"string"},"description":"Member id returned by the member list."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchCampaignSegmentMemberDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignSegmentMemberDto"}}}}},"tags":["Segments"],"security":[{"bearer":[]}],"description":"Send only the fields that change. phone must stay E.164. bsuid must stay in the provider format. The member still needs a phone or a BSUID after the update."}},"/api/v1/campaigns/segments/{segmentId}":{"get":{"operationId":"CampaignSegmentsController_get","summary":"Get a segment","parameters":[{"name":"segmentId","required":true,"in":"path","schema":{"type":"string"},"description":"Segment id returned by create or list."}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignSegmentDto"}}}}},"tags":["Segments"],"security":[{"bearer":[]}],"description":"segmentId is the id returned when the segment was created."},"patch":{"operationId":"CampaignSegmentsController_update","summary":"Update a segment","parameters":[{"name":"segmentId","required":true,"in":"path","schema":{"type":"string"},"description":"Segment id returned by create or list."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCampaignSegmentDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignSegmentDto"}}}}},"tags":["Segments"],"security":[{"bearer":[]}],"description":"Send only the fields that change. name up to 200 characters. description up to 2000 characters. segmentId is the id from create."},"delete":{"operationId":"CampaignSegmentsController_remove","summary":"Delete a segment","parameters":[{"name":"segmentId","required":true,"in":"path","schema":{"type":"string"},"description":"Segment id returned by create or list."}],"responses":{"204":{"description":""}},"tags":["Segments"],"security":[{"bearer":[]}],"description":"Deletes the segment and its members. Fails while a draft, sending, paused, or scheduled campaign still uses it."}},"/api/v1/campaigns/{campaignId}/analytics":{"get":{"operationId":"CampaignAnalyticsController_summary","summary":"Analytics summary","description":"Counts for the snapshot taken at send. dailyLimit is the channel tier, not a campaign setting. Rates are fractions from 0 to 1.","parameters":[{"name":"campaignId","required":true,"in":"path","schema":{"type":"string"},"description":"Campaign id returned by create or list."}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignAnalyticsSummaryDto"}}}}},"tags":["Analytics"],"security":[{"bearer":[]}]}},"/api/v1/campaigns/{campaignId}/analytics/recipients":{"get":{"operationId":"CampaignAnalyticsController_recipients","summary":"Recipient analytics","description":"One row per recipient. filter is a comma-separated list of sent, delivered, read, replied, failed, skipped, or cancelled. filter=clicked is rejected; use filter=replied with replyType=button. fields limits the columns. conversationId is the Inbox dialog. providerConversationId is the provider chat id. messageId and providerMessageId are the provider message id. limit max 100. cursor is nextCursor.","parameters":[{"name":"campaignId","required":true,"in":"path","schema":{"type":"string"},"description":"Campaign id returned by create or list."},{"name":"filter","required":false,"in":"query","description":"Comma-separated: sent, delivered, read, replied, failed, skipped, cancelled. filter=clicked is rejected — use replied with replyType=button.","schema":{"type":"string"}},{"name":"replied","required":false,"in":"query","description":"true keeps only people who replied. false keeps people who did not.","schema":{"enum":["true","false"],"type":"string"}},{"name":"replyType","required":false,"in":"query","description":"button keeps button taps. text keeps free-text replies.","schema":{"enum":["button","text"],"type":"string"}},{"name":"buttonId","required":false,"in":"query","description":"One template button id. Use with replyType=button.","schema":{"type":"string"}},{"name":"reason","required":false,"in":"query","description":"Exact skip or fail reason from the errors feed.","schema":{"type":"string"}},{"name":"fields","required":false,"in":"query","description":"Comma-separated columns to return. Include providerConversationId and providerMessageId when you need the provider ids. conversationId is the Inbox dialog id. messageId is the provider message id.","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Page size, from 1 to 100. Default 50.","schema":{"type":"number"}},{"name":"cursor","required":false,"in":"query","description":"nextCursor from the previous page. Leave empty for the first page.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignAnalyticsRecipientPageDto"}}}}},"tags":["Analytics"],"security":[{"bearer":[]}]}},"/api/v1/campaigns/{campaignId}/analytics/replies":{"get":{"operationId":"CampaignAnalyticsController_replies","summary":"Reply feed","parameters":[{"name":"campaignId","required":true,"in":"path","schema":{"type":"string"},"description":"Campaign id returned by create or list."},{"name":"replyType","required":false,"in":"query","description":"button keeps button taps. text keeps free-text replies. Omit to return both.","schema":{"enum":["button","text"],"type":"string"}},{"name":"buttonId","required":false,"in":"query","description":"One template button id.","schema":{"type":"string"}},{"name":"phone","required":false,"in":"query","description":"E.164 phone of one recipient.","schema":{"type":"string"}},{"name":"bsuid","required":false,"in":"query","description":"Provider BSUID of one recipient, for example ab.abc123xyz.","schema":{"type":"string"}},{"name":"dateFrom","required":false,"in":"query","description":"ISO-8601 start, inclusive, for example 2026-11-01T00:00:00Z.","schema":{"type":"string"}},{"name":"dateTo","required":false,"in":"query","description":"ISO-8601 end, inclusive, for example 2026-11-02T00:00:00Z.","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Page size, from 1 to 100. Default 50.","schema":{"type":"number"}},{"name":"cursor","required":false,"in":"query","description":"nextCursor from the previous page. Leave empty for the first page.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignAnalyticsRepliesDto"}}}}},"tags":["Analytics"],"security":[{"bearer":[]}],"description":"replyType is button or text. buttonId filters one button. phone and bsuid filter one recipient. dateFrom and dateTo are ISO-8601. providerConversationId is the provider chat id. messageId and providerMessageId are the provider message id."}},"/api/v1/campaigns/{campaignId}/analytics/errors":{"get":{"operationId":"CampaignAnalyticsController_errors","summary":"Errors by reason","parameters":[{"name":"campaignId","required":true,"in":"path","schema":{"type":"string"},"description":"Campaign id returned by create or list."},{"name":"recipientsLimit","required":false,"in":"query","description":"Recipients shown per reason. Default 20, max 100.","schema":{"type":"number"}},{"name":"type","required":false,"in":"query","description":"failed keeps send errors. skipped keeps recipients that were not sent. Omit to return both.","schema":{"enum":["failed","skipped"],"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignAnalyticsErrorsDto"}}}}},"tags":["Analytics"],"security":[{"bearer":[]}],"description":"Groups failed and skipped recipients by reason. type is failed or skipped. recipientsLimit is how many recipients to include per reason, default 20, maximum 100. Each recipient includes providerConversationId and providerMessageId."}},"/api/v1/campaigns":{"post":{"operationId":"CampaignsController_create","summary":"Create a campaign draft","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCampaignDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponseDto"}}}}},"tags":["Campaigns"],"security":[{"bearer":[]}],"description":"name is the campaign title. channelId is the channel that will send. segmentId is the audience. content.mode is template or text. For a template set content.templateName, content.language, and content.params (the sendTemplate array). content.messageSendTtlSeconds is optional, in seconds, and sits beside params. For text set content.text. status, if sent, must be draft. content.bindings maps template slot keys to data source refs (e.g. {\"1\": \"segment.name\", \"2\": \"segment.attributes.order_id\"}). Bindings work with the variables path only; combining params and bindings returns 400. content.onMissing controls behavior when a binding cannot resolve for a recipient; default is skip_recipient."},"get":{"operationId":"CampaignsController_list","summary":"List campaigns","description":"Newest first, for the whole account. channelId limits the list to those channels. Repeat the parameter or pass a comma-separated list. Omit channelId to return every channel. limit defaults to 50, maximum 100. cursor is nextCursor from the previous page.","parameters":[{"name":"limit","required":false,"in":"query","description":"Page size. Defaults to 50, maximum 100.","schema":{"type":"string"}},{"name":"cursor","required":false,"in":"query","description":"nextCursor from the previous page. Leave empty for the first page.","schema":{"type":"string"}},{"name":"channelId","required":false,"in":"query","description":"Channel id. Repeat the parameter or pass a comma-separated list. Omit to list every channel.","schema":{"type":"array","items":{}}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignPageDto"}}}}},"tags":["Campaigns"],"security":[{"bearer":[]}]}},"/api/v1/campaigns/{campaignId}/preview":{"get":{"operationId":"CampaignsController_previewCampaign","summary":"Preview a campaign","parameters":[{"name":"campaignId","required":true,"in":"path","schema":{"type":"string"},"description":"Campaign id returned by create or list."}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignPreviewDto"}}}}},"tags":["Campaigns"],"security":[{"bearer":[]}],"description":"Counts recipients and how many are outside the 24-hour window. tierDailyLimit is the channel tier. No price and no cost are returned. Nothing is sent."}},"/api/v1/campaigns/{campaignId}/send":{"post":{"operationId":"CampaignsController_send","summary":"Send or schedule a campaign","description":"Copies the segment into the send snapshot. scheduledAt is a future ISO-8601 instant with Z or a numeric offset. Omit it or send null to start now. Template sends pause when the channel tier for the rolling 24 hours is used up. There is no separate per-day field.","parameters":[{"name":"campaignId","required":true,"in":"path","schema":{"type":"string"},"description":"Campaign id returned by create or list."}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendCampaignDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponseDto"}}}}},"tags":["Campaigns"],"security":[{"bearer":[]}]}},"/api/v1/campaigns/{campaignId}/schedule":{"patch":{"operationId":"CampaignsController_schedule","summary":"Change the scheduled time","parameters":[{"name":"campaignId","required":true,"in":"path","schema":{"type":"string"},"description":"Campaign id returned by create or list."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCampaignScheduleDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponseDto"}}}}},"tags":["Campaigns"],"security":[{"bearer":[]}],"description":"scheduledAt is a new future ISO-8601 instant with Z or a numeric offset. Only a campaign that is already scheduled can be moved."}},"/api/v1/campaigns/{campaignId}/unschedule":{"post":{"operationId":"CampaignsController_unschedule","summary":"Return a scheduled campaign to draft","parameters":[{"name":"campaignId","required":true,"in":"path","schema":{"type":"string"},"description":"Campaign id returned by create or list."}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponseDto"}}}}},"tags":["Campaigns"],"security":[{"bearer":[]}],"description":"Clears scheduledAt and sets status back to draft. No body."}},"/api/v1/campaigns/{campaignId}/pause":{"post":{"operationId":"CampaignsController_pause","summary":"Pause a sending campaign","parameters":[{"name":"campaignId","required":true,"in":"path","schema":{"type":"string"},"description":"Campaign id returned by create or list."}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponseDto"}}}}},"tags":["Campaigns"],"security":[{"bearer":[]}],"description":"Stops taking new recipients from the queue. No body. Resume continues the same snapshot."}},"/api/v1/campaigns/{campaignId}/resume":{"post":{"operationId":"CampaignsController_resume","summary":"Resume a paused campaign","parameters":[{"name":"campaignId","required":true,"in":"path","schema":{"type":"string"},"description":"Campaign id returned by create or list."}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponseDto"}}}}},"tags":["Campaigns"],"security":[{"bearer":[]}],"description":"Continues the same snapshot. No body. The daily cap is still the channel tier."}},"/api/v1/campaigns/{campaignId}/complete":{"post":{"operationId":"CampaignsController_complete","summary":"Complete a campaign","parameters":[{"name":"campaignId","required":true,"in":"path","schema":{"type":"string"},"description":"Campaign id returned by create or list."}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponseDto"}}}}},"tags":["Campaigns"],"security":[{"bearer":[]}],"description":"Marks a sending or paused campaign completed and drops recipients that were not sent. No body."}},"/api/v1/campaigns/{campaignId}/test":{"post":{"operationId":"CampaignsController_test","summary":"Send one test","description":"Sends the draft content to one recipient and does not change campaign status or analytics. Provide exactly one of phone (E.164) or bsuid (provider format). A provider rejection is an error, not an accepted send. conversationId is the Inbox dialog. messageId and providerMessageId are the same provider message id, or null when the provider accepted the send without an id.","parameters":[{"name":"campaignId","required":true,"in":"path","schema":{"type":"string"},"description":"Campaign id returned by create or list."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignTestSendDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignTestSendResponseDto"}}}}},"tags":["Campaigns"],"security":[{"bearer":[]}]}},"/api/v1/campaigns/{campaignId}":{"get":{"operationId":"CampaignsController_get","summary":"Get a campaign","parameters":[{"name":"campaignId","required":true,"in":"path","schema":{"type":"string"},"description":"Campaign id returned by create or list."}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponseDto"}}}}},"tags":["Campaigns"],"security":[{"bearer":[]}],"description":"campaignId is the id from create. dailyLimit is the channel tier for a rolling 24 hours. It is not a value you set. scheduledAt is the future send time, or null."},"patch":{"operationId":"CampaignsController_update","summary":"Update a draft campaign","parameters":[{"name":"campaignId","required":true,"in":"path","schema":{"type":"string"},"description":"Campaign id returned by create or list."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCampaignDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignResponseDto"}}}}},"tags":["Campaigns"],"security":[{"bearer":[]}],"description":"Only a draft can be changed. Send at least one of name, channelId, segmentId, or content. content follows the same template and text rules as create. content.bindings and content.onMissing can be set or cleared. Combining params and bindings returns 400."}}},"info":{"title":"Campaigns API","description":"Campaigns API lets you send one message to multiple recipients. A segment can contain up to 500 people by default. To increase the limit to 10,000, contact us at [hello@1msg.io](mailto:hello@1msg.io). Inbox methods are not covered in this document.\n\nUse the API groups in this order: Segments → Campaigns → Analytics.\n\n## 1. Segments\n\nCreate a segment and add members. Each member requires a `name` and at least one of `phone` or `bsuid`.\n\n## 2. Campaigns\n\nCreate a draft with a `channelId` the API key can access and a `segmentId` from the previous step.\n\nSet `content.mode` to `text` or `template`:\n\n- Text: provide `content.text`.\n- Template: provide `content.templateName` and `content.language` (e.g. `en`).\n\nFor templates:\n\n- `content.params` uses the same format as `sendTemplate` and is forwarded to WABA as-is, supporting header images, body variables, buttons, and carousel cards.\n- `content.messageSendTtlSeconds` is optional and sets the delivery window in seconds. It belongs alongside `params`, not inside the template components.\n\nPreview the draft before sending.\n\nTo schedule a campaign, set `scheduledAt` to a future ISO 8601 timestamp with `Z` or a numeric offset, e.g. `2026-11-01T09:00:00Z`. Omit it or set it to `null` to start sending immediately.\n\nThere is no daily message-count setting. Template sends use the channel's tier limit, returned as `dailyLimit`. Session text messages sent within an open 24-hour window do not count toward this limit.\n\n## 3. Analytics\n\nRead analytics after sending to track campaign performance:\n\n- Overall statistics: total messages sent, delivered, read, and replied to.\n- Recipient-level statistics: when each message was sent, delivered and read, when the recipient replied, and their replies — including button clicks and free-text messages.\n- Button statistics: see who clicked each button and when.\n- Error statistics: see which recipients encountered errors and the corresponding error for each phone number.\n\n## 4. Campaigns webhooks\n\n1MSG sends webhook events to your configured HTTPS URL when segments or campaigns are created or updated, and when a campaign's status changes.\n\nConfigure webhooks in Settings → Developer → Webhooks.\n\n### Events\n\n- `segment.created` — A segment was created. `action` is `segment_created`.\n- `segment.updated` — A segment or its members changed. `action` can be `segment_updated`, `segment_deleted`, `member_added`, `member_updated`, `member_deleted`, or `members_replaced`. The payload does not identify the affected member.\n- `campaign.created` — A campaign draft was created. `scheduledAt` contains the scheduled send time or `null`.\n- `campaign.updated` — A campaign draft was updated. `scheduledAt` contains the scheduled send time or `null`.\n- `campaign.status_changed` — The campaign status changed to `draft`, `sending`, `pause`, `completed`, `failed`, or `scheduled`. `scheduledAt` contains the scheduled send time or `null`.\n\n## Authorization\n\nThe key must include the Campaigns scope. Issue it in Settings → Developer → API key.\n\n```\nAuthorization: Bearer 1msg_live_…\n```","version":"1.0"},"tags":[{"name":"Segments","description":"Create a segment, then add people. Each member needs a name and a phone in E.164 or a BSUID."},{"name":"Campaigns","description":"Create a draft, set the template or text, preview, then send or schedule. The daily template cap is the channel tier, not a field on the campaign."},{"name":"Analytics","description":"Read the send snapshot: who was reached, what they replied, and why a send failed. conversationId is the Inbox dialog. providerConversationId is the provider chat id. messageId and providerMessageId are the same provider message id."}],"servers":[{"url":"https://api.1msg.io","description":"Production"},{"url":"https://api.stage.1msg.io","description":"Staging"}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"API key","type":"http","description":"Key issued in Settings → Developer → API key. Inbox methods need the Inbox scope. Campaigns methods need the Campaigns scope."}},"schemas":{"CreateCampaignSegmentDto":{"type":"object","properties":{"name":{"type":"string","description":"Segment name, up to 200 characters.","example":"April buyers"},"description":{"type":"string","description":"Optional note, up to 2000 characters."}},"required":["name"]},"CampaignSegmentCreatedDto":{"type":"object","properties":{"id":{"type":"string","description":"Segment id.","example":"cm3segment01"},"name":{"type":"string","description":"Segment name, up to 200 characters.","example":"April buyers"},"description":{"type":"string","nullable":true,"description":"Optional note, up to 2000 characters, or null when none was stored.","example":"People who bought in April"},"createdAt":{"type":"string","format":"date-time","description":"When the segment was created.","example":"2026-11-01T09:00:00.000Z"}},"required":["id","name","description","createdAt"]},"CampaignSegmentPageDto":{"type":"object","properties":{"items":{"description":"Segments on this page, newest first.","type":"array","items":{"$ref":"#/components/schemas/CampaignSegmentListItemDto"}},"nextCursor":{"type":"string","nullable":true,"description":"Cursor for the next page, or null on the last page.","example":null}},"required":["items","nextCursor"]},"CampaignSegmentMemberPageDto":{"type":"object","properties":{"items":{"description":"Members on this page, newest first.","type":"array","items":{"$ref":"#/components/schemas/CampaignSegmentMemberDto"}},"nextCursor":{"type":"string","nullable":true,"description":"Cursor for the next page, or null on the last page.","example":null}},"required":["items","nextCursor"]},"AddCampaignSegmentMembersDto":{"type":"object","properties":{"members":{"description":"Non-empty list. Each item needs name and a phone or a BSUID. A duplicate phone or BSUID in the segment is rejected. The segment cannot exceed 500 members.","type":"array","items":{"$ref":"#/components/schemas/CampaignSegmentMemberInputDto"}}},"required":["members"]},"CampaignSegmentMemberBatchDto":{"type":"object","properties":{"items":{"description":"Members written by this request.","type":"array","items":{"$ref":"#/components/schemas/CampaignSegmentMemberDto"}}},"required":["items"]},"ReplaceCampaignSegmentMembersDto":{"type":"object","properties":{"members":{"description":"Replaces every current member. Same name, phone, and bsuid rules as when adding members. An empty list clears the segment. The new list cannot exceed 500 members.","type":"array","items":{"$ref":"#/components/schemas/CampaignSegmentMemberInputDto"}}},"required":["members"]},"RemoveCampaignSegmentMembersDto":{"type":"object","properties":{"memberIds":{"description":"Member ids from the member list. Other members stay.","example":["mem_1"],"type":"array","items":{"type":"string"}}},"required":["memberIds"]},"CampaignSegmentMembersRemovedDto":{"type":"object","properties":{"removed":{"type":"number","description":"How many members were deleted.","example":2}},"required":["removed"]},"PatchCampaignSegmentMemberDto":{"type":"object","properties":{"name":{"type":"string","description":"New name, up to 200 characters."},"phone":{"type":"string","description":"E.164 phone, for example +15551234567. After the update the member still needs a phone or a BSUID."},"bsuid":{"type":"string","description":"Provider BSUID, for example ab.abc123xyz. A trailing @lid is stored without it."},"attributes":{"type":"object","additionalProperties":{"type":"string"},"nullable":true,"description":"Flat JSON object of string key-value pairs. Set to null to clear. Same validation rules as when adding members."}}},"CampaignSegmentMemberDto":{"type":"object","properties":{"id":{"type":"string","description":"Member id.","example":"cm3member01"},"name":{"type":"string","description":"Member name.","example":"Ana"},"phone":{"type":"string","nullable":true,"description":"Phone in E.164, or null when the member is stored by BSUID.","example":"+15551234567"},"bsuid":{"type":"string","nullable":true,"description":"Provider BSUID without a trailing @lid, or null when the member is stored by phone.","example":"ab.abc123xyz"},"attributes":{"type":"object","additionalProperties":{"type":"string"},"nullable":true,"description":"Arbitrary key-value data for template variable bindings, or null.","example":{"order_id":"ORD-1001"}}},"required":["id","name","phone","bsuid","attributes"]},"CampaignSegmentDto":{"type":"object","properties":{"id":{"type":"string","description":"Segment id.","example":"cm3segment01"},"name":{"type":"string","description":"Segment name, up to 200 characters.","example":"April buyers"},"description":{"type":"string","nullable":true,"description":"Optional note, up to 2000 characters, or null when none was stored."},"memberCount":{"type":"number","description":"How many people are in the segment.","example":12},"createdAt":{"type":"string","format":"date-time","description":"When the segment was created.","example":"2026-11-01T09:00:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"When the segment was last updated.","example":"2026-11-01T09:00:00.000Z"}},"required":["id","name","description","memberCount","createdAt","updatedAt"]},"UpdateCampaignSegmentDto":{"type":"object","properties":{"name":{"type":"string","description":"New name, up to 200 characters. Send only the fields that change."},"description":{"type":"string","description":"New note, up to 2000 characters."}}},"CampaignAnalyticsSummaryDto":{"type":"object","properties":{"campaignId":{"type":"string","description":"Campaign id.","example":"cm3campaign01"},"status":{"type":"string","enum":["draft","sending","pause","completed","failed","scheduled"],"description":"Campaign status."},"recipients":{"type":"number","description":"Recipients in the send snapshot.","example":12},"sent":{"type":"number","description":"Recipients whose status is sent, delivered, or read.","example":10},"delivered":{"type":"number","description":"Recipients whose status is delivered or read.","example":8},"read":{"type":"number","description":"Recipients whose status is read.","example":4},"failed":{"type":"number","description":"Recipients whose status is failed.","example":1},"skipped":{"type":"number","description":"Recipients whose status is skipped.","example":1},"cancelled":{"type":"number","description":"Recipients removed from the queue before send.","example":0},"queued":{"type":"number","description":"Recipients whose status is queued or leasing.","example":0},"replied":{"type":"number","description":"Recipients who sent at least one reply.","example":2},"textReplies":{"type":"number","description":"Recipients who sent at least one text reply.","example":1},"clicks":{"type":"number","description":"Button replies in the snapshot.","example":3},"uniqueClicks":{"type":"number","description":"Recipients who clicked at least one button.","example":2},"rates":{"description":"Shares of recipients, from 0 to 1, rounded to 4 decimal places. Each rate is 0 when there are no recipients.","allOf":[{"$ref":"#/components/schemas/CampaignAnalyticsRatesDto"}]},"buttons":{"description":"Button clicks grouped by button id.","type":"array","items":{"$ref":"#/components/schemas/CampaignAnalyticsButtonDto"}},"queuedRemaining":{"type":"number","description":"Recipients still waiting to be sent.","example":0},"sentThisPortion":{"type":"number","description":"Template sends already started in the current tier window.","example":0},"dailyLimit":{"type":"number","nullable":true,"description":"How many template sends this channel may start in a rolling 24 hours, or null when the tier is unknown or unlimited.","example":1000},"nextPortionAt":{"type":"string","nullable":true,"format":"date-time","description":"When the next template portion can start, or null when a portion is not waiting.","example":null}},"required":["campaignId","status","recipients","sent","delivered","read","failed","skipped","cancelled","queued","replied","textReplies","clicks","uniqueClicks","rates","buttons","queuedRemaining","sentThisPortion","dailyLimit","nextPortionAt"]},"CampaignAnalyticsRecipientPageDto":{"type":"object","properties":{"items":{"description":"Recipients on this page. When the fields query is set, each item contains only the named keys.","type":"array","items":{"$ref":"#/components/schemas/CampaignAnalyticsRecipientDto"}},"nextCursor":{"type":"string","nullable":true,"description":"Cursor for the next page, or null on the last page.","example":null}},"required":["items","nextCursor"]},"CampaignAnalyticsRepliesDto":{"type":"object","properties":{"campaignId":{"type":"string","description":"Campaign id.","example":"cm3campaign01"},"totalReplies":{"type":"number","description":"Reply count for the whole campaign, not just this page.","example":4},"uniqueRepliers":{"type":"number","description":"How many recipients replied at least once in the whole campaign.","example":3},"items":{"description":"Replies on this page, oldest first.","type":"array","items":{"$ref":"#/components/schemas/CampaignAnalyticsReplyItemDto"}},"nextCursor":{"type":"string","nullable":true,"description":"Cursor for the next page, or null on the last page.","example":null}},"required":["campaignId","totalReplies","uniqueRepliers","items","nextCursor"]},"CampaignAnalyticsErrorsDto":{"type":"object","properties":{"campaignId":{"type":"string","description":"Campaign id.","example":"cm3campaign01"},"items":{"description":"Errors grouped by reason, code, title, and type.","type":"array","items":{"$ref":"#/components/schemas/CampaignAnalyticsErrorGroupDto"}}},"required":["campaignId","items"]},"CreateCampaignDto":{"type":"object","properties":{"name":{"type":"string","description":"Campaign title shown in the list.","example":"Spring promo"},"channelId":{"type":"string","description":"Id of the channel that sends. The key must be allowed to use this channel."},"segmentId":{"type":"string","description":"Segment id from POST /campaigns/segments. Members are copied when you send."},"content":{"description":"template or text. For a template set templateName, language, and params.","allOf":[{"$ref":"#/components/schemas/CampaignContentDto"}]},"status":{"type":"string","enum":["draft"],"description":"Only draft is accepted. Omit to store draft."}},"required":["name","channelId","segmentId","content"]},"CampaignResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Campaign id.","example":"cm3campaign01"},"name":{"type":"string","description":"Campaign title.","example":"April restock"},"channelId":{"type":"string","description":"Channel that sends the campaign.","example":"cm3channel01"},"segmentId":{"type":"string","description":"Segment used as the audience.","example":"cm3segment01"},"status":{"type":"string","enum":["draft","sending","pause","completed","failed","scheduled"],"description":"Campaign status."},"content":{"description":"Template or session text stored on the campaign.","oneOf":[{"$ref":"#/components/schemas/CampaignTextContentResponseDto"},{"$ref":"#/components/schemas/CampaignTemplateParamsContentResponseDto"},{"$ref":"#/components/schemas/CampaignTemplateVariablesContentResponseDto"}]},"sentAt":{"type":"string","nullable":true,"format":"date-time","description":"When sending started, or null if it has not started.","example":"2026-11-01T09:00:00.000Z"},"scheduledAt":{"type":"string","nullable":true,"format":"date-time","description":"UTC instant for a scheduled send, or null.","example":"2026-11-01T09:00:00.000Z"},"queuedRemaining":{"type":"number","description":"Recipients still waiting to be sent.","example":0},"sentThisPortion":{"type":"number","description":"Template sends already started in the current tier window.","example":0},"dailyLimit":{"type":"number","nullable":true,"description":"How many template sends this channel may start in a rolling 24 hours. Taken from the channel tier (waba_info.current_limit), not from a campaign setting. Null when the tier is unknown or unlimited. Session text is not counted.","example":1000},"nextPortionAt":{"type":"string","nullable":true,"format":"date-time","description":"When the next template portion can start after the tier window is full. Null when a portion is not waiting.","example":null},"createdAt":{"type":"string","format":"date-time","description":"When the campaign was created.","example":"2026-11-01T09:00:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"When the campaign was last updated.","example":"2026-11-01T09:00:00.000Z"}},"required":["id","name","channelId","segmentId","status","content","sentAt","scheduledAt","queuedRemaining","sentThisPortion","dailyLimit","nextPortionAt","createdAt","updatedAt"]},"CampaignPageDto":{"type":"object","properties":{"items":{"description":"Campaigns on this page, newest first.","type":"array","items":{"$ref":"#/components/schemas/CampaignResponseDto"}},"nextCursor":{"type":"string","nullable":true,"description":"Cursor for the next page, or null on the last page.","example":null}},"required":["items","nextCursor"]},"CampaignPreviewDto":{"type":"object","properties":{"campaignId":{"type":"string","description":"Campaign id.","example":"cm3campaign01"},"segmentId":{"type":"string","description":"Segment id used as the audience.","example":"cm3segment01"},"contentMode":{"type":"string","enum":["template","text"],"description":"Whether the campaign sends a template or session text."},"recipientCount":{"type":"number","description":"Members in the segment.","example":12},"closedWindowCount":{"type":"number","description":"Members outside the 24-hour window.","example":3},"tierDailyLimit":{"type":"number","nullable":true,"description":"How many template sends this channel may start in a rolling 24 hours. Taken from the channel tier, not from a field you set. Null when the tier is unknown or unlimited.","example":1000},"exceedsTierDailyLimit":{"type":"boolean","description":"True when a template send would pass the channel tier.","example":false},"warnings":{"description":"Warnings for this preview. Nothing is sent.","type":"array","items":{"$ref":"#/components/schemas/CampaignPreviewWarningDto"}}},"required":["campaignId","segmentId","contentMode","recipientCount","closedWindowCount","tierDailyLimit","exceedsTierDailyLimit","warnings"]},"SendCampaignDto":{"type":"object","properties":{"scheduledAt":{"type":"string","nullable":true,"description":"Future ISO-8601 instant with a Z or a numeric offset, for example 2026-11-01T09:00:00Z. Omit or null to start now. There is no per-day field. Template sends use the channel tier."}}},"UpdateCampaignScheduleDto":{"type":"object","properties":{"scheduledAt":{"type":"string","description":"New future ISO-8601 instant with a Z or a numeric offset, for example 2026-11-02T09:00:00Z. Required. Only a campaign that is already scheduled can be moved."}},"required":["scheduledAt"]},"CampaignTestSendDto":{"type":"object","properties":{"phone":{"type":"string","description":"E.164 phone, for example +15551234567. Send exactly one of phone or bsuid. Does not change campaign status or analytics."},"bsuid":{"type":"string","description":"Provider BSUID, for example ab.abc123xyz. A trailing @lid is accepted. Send exactly one of phone or bsuid."}}},"CampaignTestSendResponseDto":{"type":"object","properties":{"accepted":{"type":"boolean","description":"Always true when the test was accepted.","example":true},"campaignId":{"type":"string","description":"Campaign id.","example":"cm3campaign01"},"campaignStatus":{"type":"string","enum":["draft","sending","pause","completed","failed","scheduled"],"description":"Campaign status after the test. A test does not change it."},"excludedFromAnalytics":{"type":"boolean","description":"Always true. This send is left out of analytics.","example":true},"conversationId":{"type":"string","nullable":true,"description":"Inbox conversation id, or null when the provider did not return one.","example":"cm3dialog01"},"messageId":{"type":"string","nullable":true,"description":"Provider message id, or null when the provider accepted the send without an id.","example":"wamid.HBgM"},"providerMessageId":{"type":"string","nullable":true,"description":"Same value as messageId.","example":"wamid.HBgM"},"phone":{"type":"string","description":"E.164 phone. Present when the test was sent to a phone. Exactly one of phone or bsuid is returned.","example":"+15551234567"},"bsuid":{"type":"string","description":"Provider BSUID. Present when the test was sent to a BSUID. Exactly one of phone or bsuid is returned.","example":"ab.abc123xyz"}},"required":["accepted","campaignId","campaignStatus","excludedFromAnalytics","conversationId","messageId","providerMessageId"]},"UpdateCampaignDto":{"type":"object","properties":{"name":{"type":"string","description":"New title. Send at least one of name, channelId, segmentId, or content. Only a draft can be changed."},"channelId":{"type":"string","description":"Another channel this account owns."},"segmentId":{"type":"string","description":"Another segment id. The new members are copied when you send."},"content":{"description":"Replaces the whole content object. Same template and text rules as create.","allOf":[{"$ref":"#/components/schemas/CampaignContentDto"}]}}},"CampaignSegmentListItemDto":{"type":"object","properties":{"id":{"type":"string","description":"Segment id.","example":"cm3segment01"},"name":{"type":"string","description":"Segment name, up to 200 characters.","example":"April buyers"},"description":{"type":"string","nullable":true,"description":"Optional note, up to 2000 characters, or null when none was stored."},"memberCount":{"type":"number","description":"How many people are in the segment.","example":12}},"required":["id","name","description","memberCount"]},"CampaignSegmentMemberInputDto":{"type":"object","properties":{"name":{"type":"string","description":"Person name, up to 200 characters.","example":"Ana"},"phone":{"type":"string","description":"E.164 phone, for example +15551234567. Required when bsuid is omitted."},"bsuid":{"type":"string","description":"Provider BSUID, for example ab.abc123xyz. A trailing @lid is accepted and stored without it. Phone or BSUID is required."},"attributes":{"type":"object","additionalProperties":{"type":"string"},"example":{"order_id":"ORD-1001","city":"São Paulo"},"description":"Flat JSON object of string key-value pairs for per-recipient data. Max 50 keys, key up to 64 chars matching [a-zA-Z_][a-zA-Z0-9_]*, value up to 1024 chars, total JSON up to 10KB. Used with template variable bindings."}},"required":["name"]},"CampaignAnalyticsRatesDto":{"type":"object","properties":{"sent":{"type":"number","description":"Share of recipients counted as sent, delivered, or read.","example":0.5},"delivery":{"type":"number","description":"Share of recipients counted as delivered or read.","example":0.4},"read":{"type":"number","description":"Share of recipients counted as read.","example":0.25},"reply":{"type":"number","description":"Share of recipients who replied.","example":0.1},"click":{"type":"number","description":"Share of recipients who clicked a button.","example":0.05},"failed":{"type":"number","description":"Share of recipients counted as failed.","example":0}},"required":["sent","delivery","read","reply","click","failed"]},"CampaignAnalyticsButtonDto":{"type":"object","properties":{"id":{"type":"string","description":"Button id from the template reply.","example":"shop"},"title":{"type":"string","description":"Button title, or the button id when no title was stored.","example":"Shop"},"clicks":{"type":"number","description":"How many times this button was clicked.","example":4},"uniqueClicks":{"type":"number","description":"How many recipients clicked this button.","example":3}},"required":["id","title","clicks","uniqueClicks"]},"CampaignAnalyticsRecipientDto":{"type":"object","properties":{"phone":{"type":"string","nullable":true,"description":"Phone in E.164, or null when the recipient is stored by BSUID.","example":"+15551234567"},"bsuid":{"type":"string","nullable":true,"description":"Provider BSUID, or null when the recipient is stored by phone.","example":"ab.abc123xyz"},"name":{"type":"string","description":"Recipient name.","example":"Ana"},"conversationId":{"type":"string","nullable":true,"description":"Inbox conversation id, or null when none is linked.","example":"cm3dialog01"},"providerConversationId":{"type":"string","nullable":true,"description":"Provider chat id: phone digits plus @c.us, otherwise the BSUID plus @lid, or null.","example":"15551234567@c.us"},"messageId":{"type":"string","nullable":true,"description":"Provider message id, or null before the provider accepts the send.","example":"wamid.HBgM"},"providerMessageId":{"type":"string","nullable":true,"description":"Same value as messageId.","example":"wamid.HBgM"},"status":{"type":"string","enum":["queued","leasing","sent","delivered","read","failed","skipped","cancelled"],"description":"Snapshot delivery status."},"sentAt":{"type":"string","nullable":true,"format":"date-time","description":"When the message was sent, or null.","example":"2026-11-01T09:00:00.000Z"},"deliveredAt":{"type":"string","nullable":true,"format":"date-time","description":"When the message was delivered, or null.","example":"2026-11-01T09:00:00.000Z"},"readAt":{"type":"string","nullable":true,"format":"date-time","description":"When the message was read, or null.","example":"2026-11-01T09:00:00.000Z"},"replies":{"description":"Replies from this recipient, oldest first.","type":"array","items":{"$ref":"#/components/schemas/CampaignAnalyticsRecipientReplyDto"}},"error":{"type":"object","nullable":true,"description":"Error details, or null when the recipient has no error code, title, or failed time. When present, code, title, and failedAt are always included.","properties":{"code":{"type":"string","nullable":true,"description":"Provider or skip error code, or null when none was stored."},"title":{"type":"string","nullable":true,"description":"Error title, or null when none was stored."},"failedAt":{"type":"string","nullable":true,"format":"date-time","description":"When the send failed or was skipped, or null when no time was stored.","example":"2026-11-01T09:00:00.000Z"}}}},"required":["phone","bsuid","name","conversationId","providerConversationId","messageId","providerMessageId","status","sentAt","deliveredAt","readAt","replies","error"]},"CampaignAnalyticsReplyItemDto":{"type":"object","properties":{"type":{"type":"string","enum":["button","text"],"description":"button for a template quick reply, or text inside the 24-hour window."},"buttonId":{"type":"string","nullable":true,"description":"Button id, or null for a text reply.","example":"shop"},"text":{"type":"string","nullable":true,"description":"Reply text or button title, or null when none was stored."},"phone":{"type":"string","nullable":true,"description":"Phone in E.164, or null when the recipient is stored by BSUID.","example":"+15551234567"},"bsuid":{"type":"string","nullable":true,"description":"Provider BSUID, or null when the recipient is stored by phone.","example":"ab.abc123xyz"},"name":{"type":"string","description":"Recipient name.","example":"Ana"},"conversationId":{"type":"string","nullable":true,"description":"Inbox conversation id, or null when none is linked.","example":"cm3dialog01"},"providerConversationId":{"type":"string","nullable":true,"description":"Provider chat id: phone digits plus @c.us, otherwise the BSUID plus @lid, or null.","example":"15551234567@c.us"},"receivedAt":{"type":"string","format":"date-time","description":"When the reply was received.","example":"2026-11-01T09:00:00.000Z"},"messageId":{"type":"string","description":"Provider message id of the reply.","example":"wamid.HBgM"},"providerMessageId":{"type":"string","description":"Same value as messageId.","example":"wamid.HBgM"}},"required":["type","buttonId","text","phone","bsuid","name","conversationId","providerConversationId","receivedAt","messageId","providerMessageId"]},"CampaignAnalyticsErrorGroupDto":{"type":"object","properties":{"reason":{"type":"string","description":"Stored error reason. Groups without a reason are omitted.","example":"closed_window"},"code":{"type":"string","nullable":true,"description":"Provider or skip error code, or null when none was stored."},"title":{"type":"string","nullable":true,"description":"Error title, or null when none was stored."},"type":{"type":"string","enum":["failed","skipped"],"description":"failed is a provider failure. skipped was not sent."},"count":{"type":"number","description":"Recipients in this group.","example":2},"share":{"type":"number","description":"Share of all campaign recipients in this group, from 0 to 1, rounded to 4 decimal places.","example":0.1667},"recipients":{"description":"Recipients in this group, up to recipientsLimit.","type":"array","items":{"$ref":"#/components/schemas/CampaignAnalyticsErrorRecipientDto"}},"hasMore":{"type":"boolean","description":"True when more recipients share this reason than recipientsLimit returned.","example":false}},"required":["reason","code","title","type","count","share","recipients","hasMore"]},"CampaignContentDto":{"type":"object","properties":{"mode":{"type":"string","enum":["template","text"],"description":"template sends a WABA template. text sends session text and only reaches people inside the 24-hour window."},"templateName":{"type":"string","description":"WABA template name. Required when mode is template."},"language":{"type":"string","description":"Template language code, for example en or pt_BR. Required when mode is template."},"variables":{"type":"object","additionalProperties":{"type":"string"},"example":{"1":"Ana"},"description":"Flat body placeholders only, for example { \"1\": \"Ana\" }. A numeric key fills the body. Header, buttons, and carousel are not filled here — use params. Ignored when params is set."},"params":{"type":"array","description":"Preferred template fill. The same array sendTemplate accepts. Each item is a component with type (header, body, button, carousel, or a newer WABA type). The array is forwarded as-is, including a header image link. When this is set, variables is ignored. An empty array is valid.","example":[{"type":"header","parameters":[{"type":"image","image":{"link":"https://example.com/image.jpg"}}]},{"type":"body","parameters":[{"type":"text","text":"Ana"}]}]},"messageSendTtlSeconds":{"type":"number","example":86400,"description":"How many seconds WhatsApp keeps trying to deliver this template. Same field as sendTemplate messageSendTtlSeconds. It sits beside params, not inside the params array. Omit it to use the template default."},"bindings":{"type":"object","additionalProperties":{"type":"string"},"example":{"1":"segment.name","2":"segment.attributes.order_id"},"description":"Maps template slot keys to data source refs. Only works with the variables path (not params). Keys follow the same format as variables: numeric for body, header_N, button_url_N. Values are source references like segment.name or segment.attributes.<key>. When set alongside params, returns 400."},"onMissing":{"type":"string","enum":["skip_recipient"],"default":"skip_recipient","description":"What to do when a binding cannot be resolved for a recipient. skip_recipient (default): skip the recipient and record the reason."},"text":{"type":"string","description":"Session text. Required when mode is text. Not counted against the channel tier."}},"required":["mode"]},"CampaignTextContentResponseDto":{"type":"object","properties":{"mode":{"type":"string","enum":["text"],"example":"text","description":"Session text sent only inside the 24-hour window."},"text":{"type":"string","description":"Session text body. Empty when none was stored.","example":"Hello"}},"required":["mode","text"]},"CampaignTemplateParamsContentResponseDto":{"type":"object","properties":{"mode":{"type":"string","enum":["template"],"example":"template","description":"Approved WABA template."},"templateName":{"type":"string","description":"WABA template name. Empty when none was stored.","example":"order_update"},"language":{"type":"string","description":"Template language code. Empty when none was stored.","example":"en"},"params":{"type":"array","items":{"oneOf":[{"type":"string"},{"type":"object","additionalProperties":true}]},"description":"Template params stored for sendTemplate. Each item is a string or an object."},"messageSendTtlSeconds":{"type":"number","example":86400,"description":"Seconds WhatsApp keeps trying to deliver this template. Omitted when the template default is used."}},"required":["mode","templateName","language","params"]},"CampaignTemplateVariablesContentResponseDto":{"type":"object","properties":{"mode":{"type":"string","enum":["template"],"example":"template","description":"Approved WABA template."},"templateName":{"type":"string","description":"WABA template name. Empty when none was stored.","example":"order_update"},"language":{"type":"string","description":"Template language code. Empty when none was stored.","example":"en"},"variables":{"type":"object","additionalProperties":{"type":"string"},"example":{"1":"Ana"},"description":"Flat template placeholders. Present when params were not stored."},"messageSendTtlSeconds":{"type":"number","example":86400,"description":"Seconds WhatsApp keeps trying to deliver this template. Omitted when the template default is used."}},"required":["mode","templateName","language","variables"]},"CampaignPreviewWarningDto":{"type":"object","properties":{"code":{"type":"string","enum":["closed_window_skipped","session_consumes_free_window","exceeds_tier_daily_limit","recipient_cap_exceeded"],"description":"Warning code."},"message":{"type":"string","description":"Human-readable warning.","example":"Closed-window recipients will be skipped."}},"required":["code","message"]},"CampaignAnalyticsRecipientReplyDto":{"type":"object","properties":{"type":{"type":"string","enum":["button","text"],"description":"button for a template quick reply, or text inside the 24-hour window."},"buttonId":{"type":"string","nullable":true,"description":"Button id, or null for a text reply.","example":"shop"},"text":{"type":"string","nullable":true,"description":"Reply text or button title, or null when none was stored."},"receivedAt":{"type":"string","format":"date-time","description":"When the reply was received.","example":"2026-11-01T09:00:00.000Z"},"messageId":{"type":"string","description":"Provider message id of the reply.","example":"wamid.HBgM"},"providerMessageId":{"type":"string","description":"Same value as messageId.","example":"wamid.HBgM"}},"required":["type","buttonId","text","receivedAt","messageId","providerMessageId"]},"CampaignAnalyticsErrorRecipientDto":{"type":"object","properties":{"id":{"type":"string","description":"Recipient id.","example":"cm3recipient01"},"phone":{"type":"string","nullable":true,"description":"Phone in E.164, or null when the recipient is stored by BSUID.","example":"+15551234567"},"bsuid":{"type":"string","nullable":true,"description":"Provider BSUID, or null when the recipient is stored by phone.","example":"ab.abc123xyz"},"name":{"type":"string","description":"Recipient name.","example":"Ana"},"conversationId":{"type":"string","nullable":true,"description":"Inbox conversation id, or null when none is linked.","example":"cm3dialog01"},"messageId":{"type":"string","nullable":true,"description":"Provider message id, or null when the send did not get one.","example":"wamid.HBgM"},"providerConversationId":{"type":"string","nullable":true,"description":"Provider chat id: phone digits plus @c.us, otherwise the BSUID plus @lid, or null.","example":"15551234567@c.us"},"providerMessageId":{"type":"string","nullable":true,"description":"Same value as messageId.","example":"wamid.HBgM"}},"required":["id","phone","bsuid","name","conversationId","messageId","providerConversationId","providerMessageId"]}}}}