late-sdk 0.0.68 → 0.0.69

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +62 -0
  3. data/docs/AddBroadcastRecipientsRequest.md +20 -0
  4. data/docs/BroadcastsApi.md +699 -0
  5. data/docs/BulkCreateContactsRequest.md +24 -0
  6. data/docs/BulkCreateContactsRequestContactsInner.md +28 -0
  7. data/docs/CommentAutomationsApi.md +428 -0
  8. data/docs/ContactsApi.md +500 -0
  9. data/docs/CreateBroadcastRequest.md +32 -0
  10. data/docs/CreateBroadcastRequestMessage.md +20 -0
  11. data/docs/CreateBroadcastRequestMessageAttachmentsInner.md +22 -0
  12. data/docs/CreateBroadcastRequestSegmentFilters.md +20 -0
  13. data/docs/CreateBroadcastRequestTemplate.md +22 -0
  14. data/docs/CreateCommentAutomationRequest.md +36 -0
  15. data/docs/CreateContactRequest.md +38 -0
  16. data/docs/CreateCustomFieldRequest.md +26 -0
  17. data/docs/CreateSequenceRequest.md +32 -0
  18. data/docs/CreateSequenceRequestStepsInner.md +24 -0
  19. data/docs/CreateSequenceRequestStepsInnerMessage.md +18 -0
  20. data/docs/CustomFieldsApi.md +419 -0
  21. data/docs/EnrollContactsRequest.md +20 -0
  22. data/docs/ListCommentAutomations200Response.md +20 -0
  23. data/docs/ListCommentAutomations200ResponseAutomationsInner.md +42 -0
  24. data/docs/ListCommentAutomations200ResponseAutomationsInnerStats.md +24 -0
  25. data/docs/ScheduleBroadcastRequest.md +18 -0
  26. data/docs/SequencesApi.md +697 -0
  27. data/docs/SetContactFieldValueRequest.md +18 -0
  28. data/docs/UpdateCommentAutomationRequest.md +28 -0
  29. data/docs/UpdateContactRequest.md +32 -0
  30. data/docs/UpdateCustomFieldRequest.md +20 -0
  31. data/docs/WhatsAppApi.md +25 -25
  32. data/lib/late-sdk/api/broadcasts_api.rb +689 -0
  33. data/lib/late-sdk/api/comment_automations_api.rb +420 -0
  34. data/lib/late-sdk/api/contacts_api.rb +503 -0
  35. data/lib/late-sdk/api/custom_fields_api.rb +424 -0
  36. data/lib/late-sdk/api/sequences_api.rb +681 -0
  37. data/lib/late-sdk/api/whats_app_api.rb +50 -50
  38. data/lib/late-sdk/models/add_broadcast_recipients_request.rb +160 -0
  39. data/lib/late-sdk/models/bulk_create_contacts_request.rb +253 -0
  40. data/lib/late-sdk/models/bulk_create_contacts_request_contacts_inner.rb +228 -0
  41. data/lib/late-sdk/models/create_broadcast_request.rb +302 -0
  42. data/lib/late-sdk/models/create_broadcast_request_message.rb +158 -0
  43. data/lib/late-sdk/models/create_broadcast_request_message_attachments_inner.rb +165 -0
  44. data/lib/late-sdk/models/create_broadcast_request_segment_filters.rb +158 -0
  45. data/lib/late-sdk/models/create_broadcast_request_template.rb +168 -0
  46. data/lib/late-sdk/models/create_comment_automation_request.rb +359 -0
  47. data/lib/late-sdk/models/create_contact_request.rb +276 -0
  48. data/lib/late-sdk/models/create_custom_field_request.rb +262 -0
  49. data/lib/late-sdk/models/create_sequence_request.rb +308 -0
  50. data/lib/late-sdk/models/create_sequence_request_steps_inner.rb +208 -0
  51. data/lib/late-sdk/models/create_sequence_request_steps_inner_message.rb +147 -0
  52. data/lib/late-sdk/models/enroll_contacts_request.rb +178 -0
  53. data/lib/late-sdk/models/list_comment_automations200_response.rb +158 -0
  54. data/lib/late-sdk/models/list_comment_automations200_response_automations_inner.rb +303 -0
  55. data/lib/late-sdk/models/list_comment_automations200_response_automations_inner_stats.rb +174 -0
  56. data/lib/late-sdk/models/schedule_broadcast_request.rb +164 -0
  57. data/lib/late-sdk/models/set_contact_field_value_request.rb +150 -0
  58. data/lib/late-sdk/models/update_comment_automation_request.rb +228 -0
  59. data/lib/late-sdk/models/update_contact_request.rb +212 -0
  60. data/lib/late-sdk/models/update_custom_field_request.rb +158 -0
  61. data/lib/late-sdk/version.rb +1 -1
  62. data/lib/late-sdk.rb +28 -0
  63. data/openapi.yaml +809 -13
  64. data/spec/api/broadcasts_api_spec.rb +154 -0
  65. data/spec/api/comment_automations_api_spec.rb +108 -0
  66. data/spec/api/contacts_api_spec.rb +122 -0
  67. data/spec/api/custom_fields_api_spec.rb +105 -0
  68. data/spec/api/sequences_api_spec.rb +153 -0
  69. data/spec/api/whats_app_api_spec.rb +25 -25
  70. data/spec/models/add_broadcast_recipients_request_spec.rb +42 -0
  71. data/spec/models/bulk_create_contacts_request_contacts_inner_spec.rb +66 -0
  72. data/spec/models/bulk_create_contacts_request_spec.rb +54 -0
  73. data/spec/models/create_broadcast_request_message_attachments_inner_spec.rb +48 -0
  74. data/spec/models/create_broadcast_request_message_spec.rb +42 -0
  75. data/spec/models/create_broadcast_request_segment_filters_spec.rb +42 -0
  76. data/spec/models/create_broadcast_request_spec.rb +82 -0
  77. data/spec/models/create_broadcast_request_template_spec.rb +48 -0
  78. data/spec/models/create_comment_automation_request_spec.rb +94 -0
  79. data/spec/models/create_contact_request_spec.rb +96 -0
  80. data/spec/models/create_custom_field_request_spec.rb +64 -0
  81. data/spec/models/create_sequence_request_spec.rb +82 -0
  82. data/spec/models/create_sequence_request_steps_inner_message_spec.rb +36 -0
  83. data/spec/models/create_sequence_request_steps_inner_spec.rb +54 -0
  84. data/spec/models/enroll_contacts_request_spec.rb +42 -0
  85. data/spec/models/list_comment_automations200_response_automations_inner_spec.rb +116 -0
  86. data/spec/models/list_comment_automations200_response_automations_inner_stats_spec.rb +54 -0
  87. data/spec/models/list_comment_automations200_response_spec.rb +42 -0
  88. data/spec/models/schedule_broadcast_request_spec.rb +36 -0
  89. data/spec/models/set_contact_field_value_request_spec.rb +36 -0
  90. data/spec/models/update_comment_automation_request_spec.rb +70 -0
  91. data/spec/models/update_contact_request_spec.rb +78 -0
  92. data/spec/models/update_custom_field_request_spec.rb +42 -0
  93. data/zernio-sdk-0.0.69.gem +0 -0
  94. metadata +114 -2
  95. data/zernio-sdk-0.0.68.gem +0 -0
data/openapi.yaml CHANGED
@@ -210,6 +210,27 @@ tags:
210
210
  - name: Account Settings
211
211
  description: |
212
212
  Platform-specific account settings: Facebook persistent menu, Instagram ice breakers, and Telegram bot commands.
213
+ - name: Contacts
214
+ description: |
215
+ Cross-platform contact management (CRM). Contacts are unified identities linked to platform-specific
216
+ channels (phone, IGSID, etc.). Created automatically when messages arrive, or manually via API.
217
+ - name: Custom Fields
218
+ description: |
219
+ Custom field definitions for contacts. Define fields (text, number, date, boolean, select) that can be
220
+ set on any contact for segmentation and personalization.
221
+ - name: Broadcasts
222
+ description: |
223
+ Platform-agnostic broadcast campaigns. Send bulk messages to contacts via any inbox platform.
224
+ WhatsApp broadcasts use templates; other platforms use generic messages.
225
+ - name: Sequences
226
+ description: |
227
+ Drip campaign sequences. Send a series of messages to enrolled contacts with configurable delays
228
+ between steps. Supports auto-exit on reply or unsubscribe.
229
+ - name: Comment Automations
230
+ description: |
231
+ Comment-to-DM growth automations. Set up keyword triggers on Instagram/Facebook posts so
232
+ commenters automatically receive a DM. Supports dedup, optional public comment reply, and
233
+ auto-creates contacts.
213
234
  - name: Webhooks
214
235
  description: |
215
236
  Configure webhooks for real-time notifications. Events: post.scheduled, post.published, post.failed, post.partial, post.recycled, account.connected, account.disconnected, message.received, comment.received.
@@ -219,7 +240,9 @@ tags:
219
240
  Publishing logs for transparency and debugging. Each log includes the platform API endpoint, HTTP status code, request/response bodies, duration, and retry attempts. Logs are automatically deleted after 7 days.
220
241
  - name: WhatsApp
221
242
  description: |
222
- WhatsApp Business API for sending messages, managing contacts, templates, broadcasts, and conversations.
243
+ WhatsApp Business API. Contact, broadcast, and group endpoints are **deprecated** in favor of the
244
+ cross-platform `/v1/contacts`, `/v1/broadcasts`, and `/v1/sequences` endpoints.
245
+ Template, business profile, and phone number endpoints remain active (no cross-platform equivalent).
223
246
  All endpoints require an accountId parameter identifying the WhatsApp-connected social account.
224
247
  - name: WhatsApp Phone Numbers
225
248
  description: |
@@ -12365,15 +12388,21 @@ paths:
12365
12388
  '403':
12366
12389
  description: Inbox addon required
12367
12390
  # ──────────────────────────────────────────────────────────────────────────
12368
- # BULK SEND
12391
+ # WHATSAPP-SPECIFIC ENDPOINTS
12392
+ # Contacts, broadcasts, groups: DEPRECATED (use cross-platform endpoints)
12393
+ # Templates, business profile, phone numbers: ACTIVE (no equivalent)
12369
12394
  # ──────────────────────────────────────────────────────────────────────────
12370
12395
 
12396
+ # ── BULK SEND ──────────────────────────────────────────────────────────
12397
+
12371
12398
  /v1/whatsapp/bulk:
12372
12399
  post:
12373
12400
  operationId: sendWhatsAppBulk
12401
+ deprecated: true
12374
12402
  tags: [WhatsApp]
12375
12403
  summary: Bulk send template messages
12376
12404
  description: |
12405
+ **Deprecated.** Use `POST /v1/broadcasts` to create a broadcast, `POST /v1/broadcasts/{id}/recipients` to add recipients, then `POST /v1/broadcasts/{id}/send` to send.
12377
12406
  Send a template message to multiple recipients in a single request. Maximum 100 recipients per request.
12378
12407
  Only template messages are supported for bulk sending (not free-form text).
12379
12408
 
@@ -12473,9 +12502,11 @@ paths:
12473
12502
  /v1/whatsapp/contacts:
12474
12503
  get:
12475
12504
  operationId: getWhatsAppContacts
12505
+ deprecated: true
12476
12506
  tags: [WhatsApp]
12477
12507
  summary: List contacts
12478
12508
  description: |
12509
+ **Deprecated.** Use `GET /v1/contacts?profileId={profileId}` instead.
12479
12510
  List WhatsApp contacts for an account. Supports filtering by tags, groups, opt-in status,
12480
12511
  and text search. Returns contacts sorted by name with available filter options.
12481
12512
  security:
@@ -12581,9 +12612,11 @@ paths:
12581
12612
  '404': { description: WhatsApp account not found }
12582
12613
  post:
12583
12614
  operationId: createWhatsAppContact
12615
+ deprecated: true
12584
12616
  tags: [WhatsApp]
12585
12617
  summary: Create contact
12586
12618
  description: |
12619
+ **Deprecated.** Use `POST /v1/contacts` instead.
12587
12620
  Create a new WhatsApp contact. Phone number must be unique per account
12588
12621
  and in E.164 format (e.g., +1234567890).
12589
12622
  security:
@@ -12673,9 +12706,12 @@ paths:
12673
12706
  /v1/whatsapp/contacts/{contactId}:
12674
12707
  get:
12675
12708
  operationId: getWhatsAppContact
12709
+ deprecated: true
12676
12710
  tags: [WhatsApp]
12677
12711
  summary: Get contact
12678
- description: Retrieve a single WhatsApp contact by ID with full details.
12712
+ description: |
12713
+ **Deprecated.** Use `GET /v1/contacts/{id}` instead.
12714
+ Retrieve a single WhatsApp contact by ID with full details.
12679
12715
  security:
12680
12716
  - bearerAuth: []
12681
12717
  parameters:
@@ -12725,9 +12761,11 @@ paths:
12725
12761
  '404': { $ref: '#/components/responses/NotFound' }
12726
12762
  put:
12727
12763
  operationId: updateWhatsAppContact
12764
+ deprecated: true
12728
12765
  tags: [WhatsApp]
12729
12766
  summary: Update contact
12730
12767
  description: |
12768
+ **Deprecated.** Use `PATCH /v1/contacts/{id}` instead.
12731
12769
  Update an existing WhatsApp contact. All fields are optional; only provided fields will be updated.
12732
12770
  Custom fields are merged with existing values. Set a custom field to null to remove it.
12733
12771
  security:
@@ -12812,9 +12850,12 @@ paths:
12812
12850
  '404': { $ref: '#/components/responses/NotFound' }
12813
12851
  delete:
12814
12852
  operationId: deleteWhatsAppContact
12853
+ deprecated: true
12815
12854
  tags: [WhatsApp]
12816
12855
  summary: Delete contact
12817
- description: Permanently delete a WhatsApp contact.
12856
+ description: |
12857
+ **Deprecated.** Use `DELETE /v1/contacts/{id}` instead.
12858
+ Permanently delete a WhatsApp contact.
12818
12859
  security:
12819
12860
  - bearerAuth: []
12820
12861
  parameters:
@@ -12843,9 +12884,11 @@ paths:
12843
12884
  /v1/whatsapp/contacts/import:
12844
12885
  post:
12845
12886
  operationId: importWhatsAppContacts
12887
+ deprecated: true
12846
12888
  tags: [WhatsApp]
12847
12889
  summary: Bulk import contacts
12848
12890
  description: |
12891
+ **Deprecated.** Use `POST /v1/contacts/bulk` instead.
12849
12892
  Import up to 1000 contacts at once. Each contact requires a phone number and name.
12850
12893
  Duplicates are skipped by default. Supports default tags and groups applied to all imported contacts.
12851
12894
  security:
@@ -12949,9 +12992,11 @@ paths:
12949
12992
  /v1/whatsapp/contacts/bulk:
12950
12993
  post:
12951
12994
  operationId: bulkUpdateWhatsAppContacts
12995
+ deprecated: true
12952
12996
  tags: [WhatsApp]
12953
12997
  summary: Bulk update contacts
12954
12998
  description: |
12999
+ **Deprecated.** Use `PATCH /v1/contacts/{id}` for individual updates instead.
12955
13000
  Perform bulk operations on multiple contacts (max 500 per request). Supported actions:
12956
13001
  addTags, removeTags, addGroups, removeGroups, optIn, optOut, block, unblock.
12957
13002
  security:
@@ -13011,9 +13056,12 @@ paths:
13011
13056
  '401': { $ref: '#/components/responses/Unauthorized' }
13012
13057
  delete:
13013
13058
  operationId: bulkDeleteWhatsAppContacts
13059
+ deprecated: true
13014
13060
  tags: [WhatsApp]
13015
13061
  summary: Bulk delete contacts
13016
- description: Permanently delete multiple contacts at once (max 500 per request).
13062
+ description: |
13063
+ **Deprecated.** Use `DELETE /v1/contacts/{id}` for individual deletes instead.
13064
+ Permanently delete multiple contacts at once (max 500 per request).
13017
13065
  security:
13018
13066
  - bearerAuth: []
13019
13067
  requestBody:
@@ -13052,9 +13100,11 @@ paths:
13052
13100
  /v1/whatsapp/groups:
13053
13101
  get:
13054
13102
  operationId: getWhatsAppGroups
13103
+ deprecated: true
13055
13104
  tags: [WhatsApp]
13056
13105
  summary: List contact groups
13057
13106
  description: |
13107
+ **Deprecated.** Use contact tags via `GET /v1/contacts` for grouping instead. WhatsApp groups have no cross-platform equivalent.
13058
13108
  List all contact groups for a WhatsApp account with contact counts.
13059
13109
  Groups are derived from the groups field on contacts, not stored as separate documents.
13060
13110
  security:
@@ -13094,9 +13144,12 @@ paths:
13094
13144
  '404': { description: WhatsApp account not found }
13095
13145
  post:
13096
13146
  operationId: renameWhatsAppGroup
13147
+ deprecated: true
13097
13148
  tags: [WhatsApp]
13098
13149
  summary: Rename group
13099
- description: Rename a contact group. This updates the group name on all contacts that belong to the group.
13150
+ description: |
13151
+ **Deprecated.** Use contact tags via `PATCH /v1/contacts/{id}` instead.
13152
+ Rename a contact group. This updates the group name on all contacts that belong to the group.
13100
13153
  security:
13101
13154
  - bearerAuth: []
13102
13155
  requestBody:
@@ -13139,9 +13192,12 @@ paths:
13139
13192
  '404': { description: WhatsApp account not found }
13140
13193
  delete:
13141
13194
  operationId: deleteWhatsAppGroup
13195
+ deprecated: true
13142
13196
  tags: [WhatsApp]
13143
13197
  summary: Delete group
13144
- description: Delete a contact group. This removes the group from all contacts but does not delete the contacts themselves.
13198
+ description: |
13199
+ **Deprecated.** Use contact tags via `PATCH /v1/contacts/{id}` instead.
13200
+ Delete a contact group. This removes the group from all contacts but does not delete the contacts themselves.
13145
13201
  security:
13146
13202
  - bearerAuth: []
13147
13203
  requestBody:
@@ -13350,7 +13406,8 @@ paths:
13350
13406
  operationId: getWhatsAppTemplate
13351
13407
  tags: [WhatsApp]
13352
13408
  summary: Get template
13353
- description: Retrieve a single message template by name.
13409
+ description: |
13410
+ Retrieve a single message template by name.
13354
13411
  security:
13355
13412
  - bearerAuth: []
13356
13413
  parameters:
@@ -13451,7 +13508,8 @@ paths:
13451
13508
  operationId: deleteWhatsAppTemplate
13452
13509
  tags: [WhatsApp]
13453
13510
  summary: Delete template
13454
- description: Permanently delete a message template by name.
13511
+ description: |
13512
+ Permanently delete a message template by name.
13455
13513
  security:
13456
13514
  - bearerAuth: []
13457
13515
  parameters:
@@ -13491,9 +13549,11 @@ paths:
13491
13549
  /v1/whatsapp/broadcasts:
13492
13550
  get:
13493
13551
  operationId: getWhatsAppBroadcasts
13552
+ deprecated: true
13494
13553
  tags: [WhatsApp]
13495
13554
  summary: List broadcasts
13496
13555
  description: |
13556
+ **Deprecated.** Use `GET /v1/broadcasts?profileId={profileId}` instead.
13497
13557
  List all WhatsApp broadcasts for an account. Returns broadcasts sorted by creation date
13498
13558
  (newest first) without the full recipients list for performance.
13499
13559
  security:
@@ -13570,9 +13630,11 @@ paths:
13570
13630
  '404': { description: WhatsApp account not found }
13571
13631
  post:
13572
13632
  operationId: createWhatsAppBroadcast
13633
+ deprecated: true
13573
13634
  tags: [WhatsApp]
13574
13635
  summary: Create broadcast
13575
13636
  description: |
13637
+ **Deprecated.** Use `POST /v1/broadcasts` instead.
13576
13638
  Create a new draft broadcast. Optionally include initial recipients.
13577
13639
  After creation, add recipients and then send or schedule the broadcast.
13578
13640
  security:
@@ -13668,9 +13730,12 @@ paths:
13668
13730
  /v1/whatsapp/broadcasts/{broadcastId}:
13669
13731
  get:
13670
13732
  operationId: getWhatsAppBroadcast
13733
+ deprecated: true
13671
13734
  tags: [WhatsApp]
13672
13735
  summary: Get broadcast
13673
- description: Retrieve detailed information about a single broadcast including delivery statistics.
13736
+ description: |
13737
+ **Deprecated.** Use `GET /v1/broadcasts/{id}` instead.
13738
+ Retrieve detailed information about a single broadcast including delivery statistics.
13674
13739
  security:
13675
13740
  - bearerAuth: []
13676
13741
  parameters:
@@ -13711,9 +13776,12 @@ paths:
13711
13776
  '404': { $ref: '#/components/responses/NotFound' }
13712
13777
  delete:
13713
13778
  operationId: deleteWhatsAppBroadcast
13779
+ deprecated: true
13714
13780
  tags: [WhatsApp]
13715
13781
  summary: Delete broadcast
13716
- description: Delete a broadcast. Only draft or cancelled broadcasts can be deleted.
13782
+ description: |
13783
+ **Deprecated.** Use `DELETE /v1/broadcasts/{id}` instead.
13784
+ Delete a broadcast. Only draft or cancelled broadcasts can be deleted.
13717
13785
  security:
13718
13786
  - bearerAuth: []
13719
13787
  parameters:
@@ -13743,9 +13811,11 @@ paths:
13743
13811
  /v1/whatsapp/broadcasts/{broadcastId}/send:
13744
13812
  post:
13745
13813
  operationId: sendWhatsAppBroadcast
13814
+ deprecated: true
13746
13815
  tags: [WhatsApp]
13747
13816
  summary: Send broadcast
13748
13817
  description: |
13818
+ **Deprecated.** Use `POST /v1/broadcasts/{id}/send` instead.
13749
13819
  Start sending a broadcast immediately. The broadcast must be in draft or scheduled status
13750
13820
  and have at least one recipient. Messages are sent sequentially with rate limiting.
13751
13821
  security:
@@ -13783,9 +13853,11 @@ paths:
13783
13853
  /v1/whatsapp/broadcasts/{broadcastId}/schedule:
13784
13854
  post:
13785
13855
  operationId: scheduleWhatsAppBroadcast
13856
+ deprecated: true
13786
13857
  tags: [WhatsApp]
13787
13858
  summary: Schedule broadcast
13788
13859
  description: |
13860
+ **Deprecated.** Use `POST /v1/broadcasts/{id}/schedule` instead.
13789
13861
  Schedule a draft broadcast for future sending. The scheduled time must be in the future
13790
13862
  and no more than 30 days in advance. The broadcast must be in draft status and have recipients.
13791
13863
  security:
@@ -13832,9 +13904,11 @@ paths:
13832
13904
  '404': { $ref: '#/components/responses/NotFound' }
13833
13905
  delete:
13834
13906
  operationId: cancelWhatsAppBroadcastSchedule
13907
+ deprecated: true
13835
13908
  tags: [WhatsApp]
13836
13909
  summary: Cancel scheduled broadcast
13837
13910
  description: |
13911
+ **Deprecated.** Use `POST /v1/broadcasts/{id}/cancel` instead.
13838
13912
  Cancel a scheduled broadcast and return it to draft status. Only broadcasts in
13839
13913
  scheduled status can be cancelled.
13840
13914
  security:
@@ -13874,9 +13948,11 @@ paths:
13874
13948
  /v1/whatsapp/broadcasts/{broadcastId}/recipients:
13875
13949
  get:
13876
13950
  operationId: getWhatsAppBroadcastRecipients
13951
+ deprecated: true
13877
13952
  tags: [WhatsApp]
13878
13953
  summary: List recipients
13879
13954
  description: |
13955
+ **Deprecated.** Use `GET /v1/broadcasts/{id}/recipients` instead.
13880
13956
  List recipients of a broadcast with their delivery status. Supports filtering
13881
13957
  by delivery status and pagination.
13882
13958
  security:
@@ -13952,9 +14028,11 @@ paths:
13952
14028
  '404': { $ref: '#/components/responses/NotFound' }
13953
14029
  patch:
13954
14030
  operationId: addWhatsAppBroadcastRecipients
14031
+ deprecated: true
13955
14032
  tags: [WhatsApp]
13956
14033
  summary: Add recipients
13957
14034
  description: |
14035
+ **Deprecated.** Use `POST /v1/broadcasts/{id}/recipients` instead.
13958
14036
  Add recipients to a draft broadcast. Maximum 1000 recipients per request.
13959
14037
  Duplicate phone numbers are automatically skipped.
13960
14038
  security:
@@ -14016,9 +14094,12 @@ paths:
14016
14094
  '404': { $ref: '#/components/responses/NotFound' }
14017
14095
  delete:
14018
14096
  operationId: removeWhatsAppBroadcastRecipients
14097
+ deprecated: true
14019
14098
  tags: [WhatsApp]
14020
14099
  summary: Remove recipients
14021
- description: Remove recipients from a draft broadcast by phone number.
14100
+ description: |
14101
+ **Deprecated.** Use `POST /v1/broadcasts/{id}/recipients` with removal flag instead.
14102
+ Remove recipients from a draft broadcast by phone number.
14022
14103
  security:
14023
14104
  - bearerAuth: []
14024
14105
  parameters:
@@ -14067,7 +14148,8 @@ paths:
14067
14148
  operationId: getWhatsAppBusinessProfile
14068
14149
  tags: [WhatsApp]
14069
14150
  summary: Get business profile
14070
- description: Retrieve the WhatsApp Business profile for the account (about, address, description, email, websites, etc.).
14151
+ description: |
14152
+ Retrieve the WhatsApp Business profile for the account (about, address, description, email, websites, etc.).
14071
14153
  security:
14072
14154
  - bearerAuth: []
14073
14155
  parameters:
@@ -14483,3 +14565,717 @@ paths:
14483
14565
  '401': { $ref: '#/components/responses/Unauthorized' }
14484
14566
  '404': { $ref: '#/components/responses/NotFound' }
14485
14567
 
14568
+ # ─── Contacts ─────────────────────────────────────────────────────
14569
+
14570
+ /v1/contacts:
14571
+ get:
14572
+ operationId: listContacts
14573
+ summary: List contacts
14574
+ description: List and search contacts for a profile. Supports filtering by tags, platform, subscription status, and full-text search.
14575
+ tags: [Contacts]
14576
+ parameters:
14577
+ - { name: profileId, in: query, required: true, schema: { type: string } }
14578
+ - { name: search, in: query, schema: { type: string } }
14579
+ - { name: tag, in: query, schema: { type: string } }
14580
+ - { name: platform, in: query, schema: { type: string, enum: [instagram, facebook, telegram, twitter, bluesky, reddit, whatsapp] } }
14581
+ - { name: isSubscribed, in: query, schema: { type: string, enum: ['true', 'false'] } }
14582
+ - { name: limit, in: query, schema: { type: integer, default: 50, maximum: 200 } }
14583
+ - { name: skip, in: query, schema: { type: integer, default: 0 } }
14584
+ responses:
14585
+ '200': { description: Contacts list with pagination and filter metadata }
14586
+ '401': { $ref: '#/components/responses/Unauthorized' }
14587
+ post:
14588
+ operationId: createContact
14589
+ summary: Create a contact
14590
+ description: Create a new contact. Optionally create a platform channel in the same request by providing accountId, platform, and platformIdentifier.
14591
+ tags: [Contacts]
14592
+ requestBody:
14593
+ required: true
14594
+ content:
14595
+ application/json:
14596
+ schema:
14597
+ type: object
14598
+ required: [profileId, name]
14599
+ properties:
14600
+ profileId: { type: string }
14601
+ name: { type: string }
14602
+ email: { type: string }
14603
+ company: { type: string }
14604
+ tags: { type: array, items: { type: string } }
14605
+ isSubscribed: { type: boolean, default: true }
14606
+ notes: { type: string }
14607
+ accountId: { type: string, description: Optional. Creates a channel if provided with platform + platformIdentifier }
14608
+ platform: { type: string }
14609
+ platformIdentifier: { type: string }
14610
+ displayIdentifier: { type: string }
14611
+ responses:
14612
+ '200': { description: Contact created }
14613
+ '401': { $ref: '#/components/responses/Unauthorized' }
14614
+ '409': { description: Duplicate contact }
14615
+
14616
+ /v1/contacts/{contactId}:
14617
+ get:
14618
+ operationId: getContact
14619
+ summary: Get contact with channels
14620
+ tags: [Contacts]
14621
+ parameters:
14622
+ - { name: contactId, in: path, required: true, schema: { type: string } }
14623
+ responses:
14624
+ '200': { description: Contact with channels }
14625
+ '401': { $ref: '#/components/responses/Unauthorized' }
14626
+ '404': { $ref: '#/components/responses/NotFound' }
14627
+ patch:
14628
+ operationId: updateContact
14629
+ summary: Update a contact
14630
+ tags: [Contacts]
14631
+ parameters:
14632
+ - { name: contactId, in: path, required: true, schema: { type: string } }
14633
+ requestBody:
14634
+ content:
14635
+ application/json:
14636
+ schema:
14637
+ type: object
14638
+ properties:
14639
+ name: { type: string }
14640
+ email: { type: string }
14641
+ company: { type: string }
14642
+ avatarUrl: { type: string }
14643
+ tags: { type: array, items: { type: string } }
14644
+ isSubscribed: { type: boolean }
14645
+ isBlocked: { type: boolean }
14646
+ notes: { type: string }
14647
+ responses:
14648
+ '200': { description: Contact updated }
14649
+ '401': { $ref: '#/components/responses/Unauthorized' }
14650
+ '404': { $ref: '#/components/responses/NotFound' }
14651
+ delete:
14652
+ operationId: deleteContact
14653
+ summary: Delete a contact
14654
+ tags: [Contacts]
14655
+ parameters:
14656
+ - { name: contactId, in: path, required: true, schema: { type: string } }
14657
+ responses:
14658
+ '200': { description: Contact deleted }
14659
+ '401': { $ref: '#/components/responses/Unauthorized' }
14660
+ '404': { $ref: '#/components/responses/NotFound' }
14661
+
14662
+ /v1/contacts/{contactId}/channels:
14663
+ get:
14664
+ operationId: getContactChannels
14665
+ summary: List channels for a contact
14666
+ tags: [Contacts]
14667
+ parameters:
14668
+ - { name: contactId, in: path, required: true, schema: { type: string } }
14669
+ responses:
14670
+ '200': { description: List of contact channels }
14671
+ '401': { $ref: '#/components/responses/Unauthorized' }
14672
+ '404': { $ref: '#/components/responses/NotFound' }
14673
+
14674
+ /v1/contacts/bulk:
14675
+ post:
14676
+ operationId: bulkCreateContacts
14677
+ summary: Bulk create contacts
14678
+ description: Import up to 1000 contacts at a time. Skips duplicates.
14679
+ tags: [Contacts]
14680
+ requestBody:
14681
+ required: true
14682
+ content:
14683
+ application/json:
14684
+ schema:
14685
+ type: object
14686
+ required: [profileId, accountId, platform, contacts]
14687
+ properties:
14688
+ profileId: { type: string }
14689
+ accountId: { type: string }
14690
+ platform: { type: string }
14691
+ contacts:
14692
+ type: array
14693
+ maxItems: 1000
14694
+ items:
14695
+ type: object
14696
+ required: [name, platformIdentifier]
14697
+ properties:
14698
+ name: { type: string }
14699
+ platformIdentifier: { type: string }
14700
+ displayIdentifier: { type: string }
14701
+ email: { type: string }
14702
+ company: { type: string }
14703
+ tags: { type: array, items: { type: string } }
14704
+ responses:
14705
+ '200': { description: Bulk import results }
14706
+ '401': { $ref: '#/components/responses/Unauthorized' }
14707
+
14708
+ /v1/contacts/{contactId}/fields/{slug}:
14709
+ put:
14710
+ operationId: setContactFieldValue
14711
+ summary: Set a custom field value
14712
+ tags: [Custom Fields]
14713
+ parameters:
14714
+ - { name: contactId, in: path, required: true, schema: { type: string } }
14715
+ - { name: slug, in: path, required: true, schema: { type: string } }
14716
+ requestBody:
14717
+ required: true
14718
+ content:
14719
+ application/json:
14720
+ schema:
14721
+ type: object
14722
+ required: [value]
14723
+ properties:
14724
+ value: { description: Field value (type depends on field definition) }
14725
+ responses:
14726
+ '200': { description: Field value set }
14727
+ '401': { $ref: '#/components/responses/Unauthorized' }
14728
+ '404': { $ref: '#/components/responses/NotFound' }
14729
+ delete:
14730
+ operationId: clearContactFieldValue
14731
+ summary: Clear a custom field value
14732
+ tags: [Custom Fields]
14733
+ parameters:
14734
+ - { name: contactId, in: path, required: true, schema: { type: string } }
14735
+ - { name: slug, in: path, required: true, schema: { type: string } }
14736
+ responses:
14737
+ '200': { description: Field value cleared }
14738
+ '401': { $ref: '#/components/responses/Unauthorized' }
14739
+ '404': { $ref: '#/components/responses/NotFound' }
14740
+
14741
+ # ─── Custom Fields ────────────────────────────────────────────────
14742
+
14743
+ /v1/custom-fields:
14744
+ get:
14745
+ operationId: listCustomFields
14746
+ summary: List custom field definitions
14747
+ tags: [Custom Fields]
14748
+ parameters:
14749
+ - { name: profileId, in: query, required: true, schema: { type: string } }
14750
+ responses:
14751
+ '200': { description: List of custom field definitions }
14752
+ '401': { $ref: '#/components/responses/Unauthorized' }
14753
+ post:
14754
+ operationId: createCustomField
14755
+ summary: Create a custom field definition
14756
+ tags: [Custom Fields]
14757
+ requestBody:
14758
+ required: true
14759
+ content:
14760
+ application/json:
14761
+ schema:
14762
+ type: object
14763
+ required: [profileId, name, type]
14764
+ properties:
14765
+ profileId: { type: string }
14766
+ name: { type: string }
14767
+ slug: { type: string, description: Auto-generated from name if not provided }
14768
+ type: { type: string, enum: [text, number, date, boolean, select] }
14769
+ options: { type: array, items: { type: string }, description: Required for select type }
14770
+ responses:
14771
+ '200': { description: Custom field created }
14772
+ '401': { $ref: '#/components/responses/Unauthorized' }
14773
+ '409': { description: Duplicate slug }
14774
+
14775
+ /v1/custom-fields/{fieldId}:
14776
+ patch:
14777
+ operationId: updateCustomField
14778
+ summary: Update a custom field definition
14779
+ tags: [Custom Fields]
14780
+ parameters:
14781
+ - { name: fieldId, in: path, required: true, schema: { type: string } }
14782
+ requestBody:
14783
+ content:
14784
+ application/json:
14785
+ schema:
14786
+ type: object
14787
+ properties:
14788
+ name: { type: string }
14789
+ options: { type: array, items: { type: string } }
14790
+ responses:
14791
+ '200': { description: Custom field updated }
14792
+ '401': { $ref: '#/components/responses/Unauthorized' }
14793
+ '404': { $ref: '#/components/responses/NotFound' }
14794
+ delete:
14795
+ operationId: deleteCustomField
14796
+ summary: Delete a custom field definition
14797
+ tags: [Custom Fields]
14798
+ parameters:
14799
+ - { name: fieldId, in: path, required: true, schema: { type: string } }
14800
+ responses:
14801
+ '200': { description: Custom field deleted }
14802
+ '401': { $ref: '#/components/responses/Unauthorized' }
14803
+ '404': { $ref: '#/components/responses/NotFound' }
14804
+
14805
+ # ─── Broadcasts ───────────────────────────────────────────────────
14806
+
14807
+ /v1/broadcasts:
14808
+ get:
14809
+ operationId: listBroadcasts
14810
+ summary: List broadcasts
14811
+ tags: [Broadcasts]
14812
+ parameters:
14813
+ - { name: profileId, in: query, required: true, schema: { type: string } }
14814
+ - { name: status, in: query, schema: { type: string, enum: [draft, scheduled, sending, completed, failed, cancelled] } }
14815
+ - { name: platform, in: query, schema: { type: string } }
14816
+ - { name: limit, in: query, schema: { type: integer, default: 50 } }
14817
+ - { name: skip, in: query, schema: { type: integer, default: 0 } }
14818
+ responses:
14819
+ '200': { description: Broadcasts list }
14820
+ '401': { $ref: '#/components/responses/Unauthorized' }
14821
+ post:
14822
+ operationId: createBroadcast
14823
+ summary: Create a broadcast draft
14824
+ tags: [Broadcasts]
14825
+ requestBody:
14826
+ required: true
14827
+ content:
14828
+ application/json:
14829
+ schema:
14830
+ type: object
14831
+ required: [profileId, accountId, platform, name]
14832
+ properties:
14833
+ profileId: { type: string }
14834
+ accountId: { type: string }
14835
+ platform: { type: string, enum: [instagram, facebook, telegram, twitter, bluesky, reddit, whatsapp] }
14836
+ name: { type: string }
14837
+ description: { type: string }
14838
+ message:
14839
+ type: object
14840
+ properties:
14841
+ text: { type: string }
14842
+ attachments: { type: array, items: { type: object, properties: { type: { type: string }, url: { type: string }, filename: { type: string } } } }
14843
+ template:
14844
+ type: object
14845
+ description: WhatsApp template (required when platform is whatsapp)
14846
+ properties:
14847
+ name: { type: string }
14848
+ language: { type: string }
14849
+ components: { type: array }
14850
+ segmentFilters:
14851
+ type: object
14852
+ properties:
14853
+ tags: { type: array, items: { type: string } }
14854
+ isSubscribed: { type: boolean }
14855
+ responses:
14856
+ '200': { description: Broadcast created }
14857
+ '401': { $ref: '#/components/responses/Unauthorized' }
14858
+
14859
+ /v1/broadcasts/{broadcastId}:
14860
+ get:
14861
+ operationId: getBroadcast
14862
+ summary: Get broadcast details
14863
+ tags: [Broadcasts]
14864
+ parameters:
14865
+ - { name: broadcastId, in: path, required: true, schema: { type: string } }
14866
+ responses:
14867
+ '200': { description: Broadcast details with stats }
14868
+ '401': { $ref: '#/components/responses/Unauthorized' }
14869
+ '404': { $ref: '#/components/responses/NotFound' }
14870
+ patch:
14871
+ operationId: updateBroadcast
14872
+ summary: Update a broadcast
14873
+ tags: [Broadcasts]
14874
+ parameters:
14875
+ - { name: broadcastId, in: path, required: true, schema: { type: string } }
14876
+ responses:
14877
+ '200': { description: Broadcast updated }
14878
+ '401': { $ref: '#/components/responses/Unauthorized' }
14879
+ '404': { $ref: '#/components/responses/NotFound' }
14880
+ delete:
14881
+ operationId: deleteBroadcast
14882
+ summary: Delete a broadcast (draft only)
14883
+ tags: [Broadcasts]
14884
+ parameters:
14885
+ - { name: broadcastId, in: path, required: true, schema: { type: string } }
14886
+ responses:
14887
+ '200': { description: Broadcast deleted }
14888
+ '401': { $ref: '#/components/responses/Unauthorized' }
14889
+ '404': { $ref: '#/components/responses/NotFound' }
14890
+
14891
+ /v1/broadcasts/{broadcastId}/send:
14892
+ post:
14893
+ operationId: sendBroadcast
14894
+ summary: Trigger immediate send
14895
+ tags: [Broadcasts]
14896
+ parameters:
14897
+ - { name: broadcastId, in: path, required: true, schema: { type: string } }
14898
+ responses:
14899
+ '200': { description: Broadcast sending started }
14900
+ '400': { description: Invalid status or no recipients }
14901
+ '401': { $ref: '#/components/responses/Unauthorized' }
14902
+ '404': { $ref: '#/components/responses/NotFound' }
14903
+
14904
+ /v1/broadcasts/{broadcastId}/schedule:
14905
+ post:
14906
+ operationId: scheduleBroadcast
14907
+ summary: Schedule broadcast for later
14908
+ tags: [Broadcasts]
14909
+ parameters:
14910
+ - { name: broadcastId, in: path, required: true, schema: { type: string } }
14911
+ requestBody:
14912
+ required: true
14913
+ content:
14914
+ application/json:
14915
+ schema:
14916
+ type: object
14917
+ required: [scheduledAt]
14918
+ properties:
14919
+ scheduledAt: { type: string, format: date-time }
14920
+ responses:
14921
+ '200': { description: Broadcast scheduled }
14922
+ '400': { description: Invalid date or status }
14923
+ '401': { $ref: '#/components/responses/Unauthorized' }
14924
+ '404': { $ref: '#/components/responses/NotFound' }
14925
+
14926
+ /v1/broadcasts/{broadcastId}/cancel:
14927
+ post:
14928
+ operationId: cancelBroadcast
14929
+ summary: Cancel a broadcast
14930
+ tags: [Broadcasts]
14931
+ parameters:
14932
+ - { name: broadcastId, in: path, required: true, schema: { type: string } }
14933
+ responses:
14934
+ '200': { description: Broadcast cancelled }
14935
+ '400': { description: Cannot cancel in current status }
14936
+ '401': { $ref: '#/components/responses/Unauthorized' }
14937
+ '404': { $ref: '#/components/responses/NotFound' }
14938
+
14939
+ /v1/broadcasts/{broadcastId}/recipients:
14940
+ get:
14941
+ operationId: listBroadcastRecipients
14942
+ summary: List broadcast recipients
14943
+ tags: [Broadcasts]
14944
+ parameters:
14945
+ - { name: broadcastId, in: path, required: true, schema: { type: string } }
14946
+ - { name: status, in: query, schema: { type: string, enum: [pending, sent, delivered, read, failed] } }
14947
+ - { name: limit, in: query, schema: { type: integer, default: 50 } }
14948
+ - { name: skip, in: query, schema: { type: integer, default: 0 } }
14949
+ responses:
14950
+ '200': { description: Recipients list with delivery status }
14951
+ '401': { $ref: '#/components/responses/Unauthorized' }
14952
+ '404': { $ref: '#/components/responses/NotFound' }
14953
+ post:
14954
+ operationId: addBroadcastRecipients
14955
+ summary: Add recipients to a broadcast
14956
+ tags: [Broadcasts]
14957
+ parameters:
14958
+ - { name: broadcastId, in: path, required: true, schema: { type: string } }
14959
+ requestBody:
14960
+ required: true
14961
+ content:
14962
+ application/json:
14963
+ schema:
14964
+ type: object
14965
+ properties:
14966
+ contactIds: { type: array, items: { type: string }, description: Specific contact IDs to add }
14967
+ useSegment: { type: boolean, description: Auto-populate from broadcast segment filters }
14968
+ responses:
14969
+ '200': { description: Recipients added }
14970
+ '401': { $ref: '#/components/responses/Unauthorized' }
14971
+ '404': { $ref: '#/components/responses/NotFound' }
14972
+
14973
+ # ─── Sequences ────────────────────────────────────────────────────
14974
+
14975
+ /v1/sequences:
14976
+ get:
14977
+ operationId: listSequences
14978
+ summary: List sequences
14979
+ tags: [Sequences]
14980
+ parameters:
14981
+ - { name: profileId, in: query, required: true, schema: { type: string } }
14982
+ - { name: status, in: query, schema: { type: string, enum: [draft, active, paused] } }
14983
+ - { name: limit, in: query, schema: { type: integer, default: 50 } }
14984
+ - { name: skip, in: query, schema: { type: integer, default: 0 } }
14985
+ responses:
14986
+ '200': { description: Sequences list }
14987
+ '401': { $ref: '#/components/responses/Unauthorized' }
14988
+ post:
14989
+ operationId: createSequence
14990
+ summary: Create a sequence
14991
+ tags: [Sequences]
14992
+ requestBody:
14993
+ required: true
14994
+ content:
14995
+ application/json:
14996
+ schema:
14997
+ type: object
14998
+ required: [profileId, accountId, platform, name]
14999
+ properties:
15000
+ profileId: { type: string }
15001
+ accountId: { type: string }
15002
+ platform: { type: string, enum: [instagram, facebook, telegram, twitter, bluesky, reddit, whatsapp] }
15003
+ name: { type: string }
15004
+ description: { type: string }
15005
+ steps:
15006
+ type: array
15007
+ items:
15008
+ type: object
15009
+ required: [order, delayMinutes]
15010
+ properties:
15011
+ order: { type: integer }
15012
+ delayMinutes: { type: integer }
15013
+ message: { type: object, properties: { text: { type: string } } }
15014
+ template: { type: object, properties: { name: { type: string }, language: { type: string } } }
15015
+ exitOnReply: { type: boolean, default: true }
15016
+ exitOnUnsubscribe: { type: boolean, default: true }
15017
+ responses:
15018
+ '200': { description: Sequence created }
15019
+ '401': { $ref: '#/components/responses/Unauthorized' }
15020
+
15021
+ /v1/sequences/{sequenceId}:
15022
+ get:
15023
+ operationId: getSequence
15024
+ summary: Get sequence with steps
15025
+ tags: [Sequences]
15026
+ parameters:
15027
+ - { name: sequenceId, in: path, required: true, schema: { type: string } }
15028
+ responses:
15029
+ '200': { description: Sequence details with steps }
15030
+ '401': { $ref: '#/components/responses/Unauthorized' }
15031
+ '404': { $ref: '#/components/responses/NotFound' }
15032
+ patch:
15033
+ operationId: updateSequence
15034
+ summary: Update a sequence
15035
+ tags: [Sequences]
15036
+ parameters:
15037
+ - { name: sequenceId, in: path, required: true, schema: { type: string } }
15038
+ responses:
15039
+ '200': { description: Sequence updated }
15040
+ '401': { $ref: '#/components/responses/Unauthorized' }
15041
+ '404': { $ref: '#/components/responses/NotFound' }
15042
+ delete:
15043
+ operationId: deleteSequence
15044
+ summary: Delete a sequence
15045
+ tags: [Sequences]
15046
+ parameters:
15047
+ - { name: sequenceId, in: path, required: true, schema: { type: string } }
15048
+ responses:
15049
+ '200': { description: Sequence deleted }
15050
+ '401': { $ref: '#/components/responses/Unauthorized' }
15051
+ '404': { $ref: '#/components/responses/NotFound' }
15052
+
15053
+ /v1/sequences/{sequenceId}/activate:
15054
+ post:
15055
+ operationId: activateSequence
15056
+ summary: Activate a sequence
15057
+ tags: [Sequences]
15058
+ parameters:
15059
+ - { name: sequenceId, in: path, required: true, schema: { type: string } }
15060
+ responses:
15061
+ '200': { description: Sequence activated }
15062
+ '400': { description: Invalid status or no steps }
15063
+ '401': { $ref: '#/components/responses/Unauthorized' }
15064
+ '404': { $ref: '#/components/responses/NotFound' }
15065
+
15066
+ /v1/sequences/{sequenceId}/pause:
15067
+ post:
15068
+ operationId: pauseSequence
15069
+ summary: Pause a sequence
15070
+ tags: [Sequences]
15071
+ parameters:
15072
+ - { name: sequenceId, in: path, required: true, schema: { type: string } }
15073
+ responses:
15074
+ '200': { description: Sequence paused }
15075
+ '400': { description: Sequence is not active }
15076
+ '401': { $ref: '#/components/responses/Unauthorized' }
15077
+ '404': { $ref: '#/components/responses/NotFound' }
15078
+
15079
+ /v1/sequences/{sequenceId}/enroll:
15080
+ post:
15081
+ operationId: enrollContacts
15082
+ summary: Enroll contacts in a sequence
15083
+ tags: [Sequences]
15084
+ parameters:
15085
+ - { name: sequenceId, in: path, required: true, schema: { type: string } }
15086
+ requestBody:
15087
+ required: true
15088
+ content:
15089
+ application/json:
15090
+ schema:
15091
+ type: object
15092
+ required: [contactIds]
15093
+ properties:
15094
+ contactIds: { type: array, items: { type: string } }
15095
+ channelIds: { type: array, items: { type: string }, description: Optional. Auto-detected if not provided. }
15096
+ responses:
15097
+ '200': { description: Enrollment results }
15098
+ '401': { $ref: '#/components/responses/Unauthorized' }
15099
+ '404': { $ref: '#/components/responses/NotFound' }
15100
+
15101
+ /v1/sequences/{sequenceId}/enroll/{contactId}:
15102
+ delete:
15103
+ operationId: unenrollContact
15104
+ summary: Unenroll a contact from a sequence
15105
+ tags: [Sequences]
15106
+ parameters:
15107
+ - { name: sequenceId, in: path, required: true, schema: { type: string } }
15108
+ - { name: contactId, in: path, required: true, schema: { type: string } }
15109
+ responses:
15110
+ '200': { description: Contact unenrolled }
15111
+ '401': { $ref: '#/components/responses/Unauthorized' }
15112
+ '404': { $ref: '#/components/responses/NotFound' }
15113
+
15114
+ /v1/sequences/{sequenceId}/enrollments:
15115
+ get:
15116
+ operationId: listSequenceEnrollments
15117
+ summary: List enrollments for a sequence
15118
+ tags: [Sequences]
15119
+ parameters:
15120
+ - { name: sequenceId, in: path, required: true, schema: { type: string } }
15121
+ - { name: status, in: query, schema: { type: string, enum: [active, completed, exited, paused] } }
15122
+ - { name: limit, in: query, schema: { type: integer, default: 50 } }
15123
+ - { name: skip, in: query, schema: { type: integer, default: 0 } }
15124
+ responses:
15125
+ '200': { description: Enrollments list with progress }
15126
+ '401': { $ref: '#/components/responses/Unauthorized' }
15127
+ '404': { $ref: '#/components/responses/NotFound' }
15128
+
15129
+ # ──────────────────────────────────────────────────────────────────────────
15130
+ # COMMENT AUTOMATIONS (Comment-to-DM)
15131
+ # ──────────────────────────────────────────────────────────────────────────
15132
+
15133
+ /v1/comment-automations:
15134
+ get:
15135
+ operationId: listCommentAutomations
15136
+ tags: [Comment Automations]
15137
+ summary: List comment-to-DM automations
15138
+ description: List all comment-to-DM automations for a profile. Returns automations with their stats.
15139
+ security:
15140
+ - bearerAuth: []
15141
+ parameters:
15142
+ - { name: profileId, in: query, required: true, schema: { type: string }, description: Profile ID }
15143
+ responses:
15144
+ '200':
15145
+ description: Automations list
15146
+ content:
15147
+ application/json:
15148
+ schema:
15149
+ type: object
15150
+ properties:
15151
+ success: { type: boolean }
15152
+ automations:
15153
+ type: array
15154
+ items:
15155
+ type: object
15156
+ properties:
15157
+ id: { type: string }
15158
+ name: { type: string }
15159
+ platform: { type: string, enum: [instagram, facebook] }
15160
+ accountId: { type: string }
15161
+ platformPostId: { type: string }
15162
+ postTitle: { type: string }
15163
+ keywords: { type: array, items: { type: string } }
15164
+ matchMode: { type: string, enum: [exact, contains] }
15165
+ dmMessage: { type: string }
15166
+ commentReply: { type: string }
15167
+ isActive: { type: boolean }
15168
+ stats:
15169
+ type: object
15170
+ properties:
15171
+ triggered: { type: integer }
15172
+ dmsSent: { type: integer }
15173
+ dmsFailed: { type: integer }
15174
+ uniqueContacts: { type: integer }
15175
+ createdAt: { type: string, format: date-time }
15176
+ '401': { $ref: '#/components/responses/Unauthorized' }
15177
+ post:
15178
+ operationId: createCommentAutomation
15179
+ tags: [Comment Automations]
15180
+ summary: Create a comment-to-DM automation
15181
+ description: |
15182
+ Create a keyword-triggered DM automation on an Instagram or Facebook post.
15183
+ When someone comments a matching keyword, they automatically receive a DM.
15184
+ Only one active automation per post is allowed.
15185
+ security:
15186
+ - bearerAuth: []
15187
+ requestBody:
15188
+ required: true
15189
+ content:
15190
+ application/json:
15191
+ schema:
15192
+ type: object
15193
+ required: [profileId, accountId, platformPostId, name, dmMessage]
15194
+ properties:
15195
+ profileId: { type: string }
15196
+ accountId: { type: string, description: Instagram or Facebook account ID }
15197
+ platformPostId: { type: string, description: Platform media/post ID }
15198
+ postId: { type: string, description: Zernio post ID (optional) }
15199
+ postTitle: { type: string, description: Post content snippet for display }
15200
+ name: { type: string, description: Automation label }
15201
+ keywords:
15202
+ type: array
15203
+ items: { type: string }
15204
+ description: Trigger keywords (empty = any comment triggers)
15205
+ matchMode: { type: string, enum: [exact, contains], default: contains }
15206
+ dmMessage: { type: string, description: DM text to send to commenter }
15207
+ commentReply: { type: string, description: Optional public reply to the comment }
15208
+ responses:
15209
+ '200': { description: Automation created }
15210
+ '400': { description: Validation error }
15211
+ '401': { $ref: '#/components/responses/Unauthorized' }
15212
+ '409': { description: Active automation already exists for this post }
15213
+
15214
+ /v1/comment-automations/{automationId}:
15215
+ get:
15216
+ operationId: getCommentAutomation
15217
+ tags: [Comment Automations]
15218
+ summary: Get automation details with recent logs
15219
+ security:
15220
+ - bearerAuth: []
15221
+ parameters:
15222
+ - { name: automationId, in: path, required: true, schema: { type: string } }
15223
+ responses:
15224
+ '200': { description: Automation details with stats and recent trigger logs }
15225
+ '401': { $ref: '#/components/responses/Unauthorized' }
15226
+ '404': { $ref: '#/components/responses/NotFound' }
15227
+ patch:
15228
+ operationId: updateCommentAutomation
15229
+ tags: [Comment Automations]
15230
+ summary: Update automation settings
15231
+ security:
15232
+ - bearerAuth: []
15233
+ parameters:
15234
+ - { name: automationId, in: path, required: true, schema: { type: string } }
15235
+ requestBody:
15236
+ content:
15237
+ application/json:
15238
+ schema:
15239
+ type: object
15240
+ properties:
15241
+ name: { type: string }
15242
+ keywords: { type: array, items: { type: string } }
15243
+ matchMode: { type: string, enum: [exact, contains] }
15244
+ dmMessage: { type: string }
15245
+ commentReply: { type: string }
15246
+ isActive: { type: boolean }
15247
+ responses:
15248
+ '200': { description: Automation updated }
15249
+ '401': { $ref: '#/components/responses/Unauthorized' }
15250
+ '404': { $ref: '#/components/responses/NotFound' }
15251
+ delete:
15252
+ operationId: deleteCommentAutomation
15253
+ tags: [Comment Automations]
15254
+ summary: Delete automation and all logs
15255
+ security:
15256
+ - bearerAuth: []
15257
+ parameters:
15258
+ - { name: automationId, in: path, required: true, schema: { type: string } }
15259
+ responses:
15260
+ '200': { description: Automation deleted }
15261
+ '401': { $ref: '#/components/responses/Unauthorized' }
15262
+ '404': { $ref: '#/components/responses/NotFound' }
15263
+
15264
+ /v1/comment-automations/{automationId}/logs:
15265
+ get:
15266
+ operationId: listCommentAutomationLogs
15267
+ tags: [Comment Automations]
15268
+ summary: List trigger logs for an automation
15269
+ description: Paginated list of every comment that triggered this automation, with send status and commenter info.
15270
+ security:
15271
+ - bearerAuth: []
15272
+ parameters:
15273
+ - { name: automationId, in: path, required: true, schema: { type: string } }
15274
+ - { name: status, in: query, schema: { type: string, enum: [sent, failed, skipped] }, description: Filter by result status }
15275
+ - { name: limit, in: query, schema: { type: integer, default: 50 } }
15276
+ - { name: skip, in: query, schema: { type: integer, default: 0 } }
15277
+ responses:
15278
+ '200': { description: Trigger logs with pagination }
15279
+ '401': { $ref: '#/components/responses/Unauthorized' }
15280
+ '404': { $ref: '#/components/responses/NotFound' }
15281
+