late-sdk 0.0.119 → 0.0.121

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -2
  3. data/docs/AccountsApi.md +72 -0
  4. data/docs/AdCampaignsApi.md +6 -2
  5. data/docs/AdsApi.md +11 -70
  6. data/docs/ConnectApi.md +3 -3
  7. data/docs/DisconnectAdsRequest.md +18 -0
  8. data/docs/WebhookEventsApi.md +69 -0
  9. data/docs/WebhookPayloadMessageSent.md +28 -0
  10. data/docs/WebhookPayloadMessageSentMessage.md +36 -0
  11. data/docs/WebhookPayloadMessageSentMessageSender.md +24 -0
  12. data/lib/late-sdk/api/accounts_api.rb +74 -0
  13. data/lib/late-sdk/api/ad_campaigns_api.rb +8 -2
  14. data/lib/late-sdk/api/ads_api.rb +16 -61
  15. data/lib/late-sdk/api/connect_api.rb +4 -4
  16. data/lib/late-sdk/api/webhook_events_api.rb +66 -0
  17. data/lib/late-sdk/api/webhooks_api.rb +1 -1
  18. data/lib/late-sdk/models/disconnect_ads_request.rb +189 -0
  19. data/lib/late-sdk/models/webhook_log.rb +2 -2
  20. data/lib/late-sdk/models/webhook_payload_message_sent.rb +320 -0
  21. data/lib/late-sdk/models/webhook_payload_message_sent_message.rb +430 -0
  22. data/lib/late-sdk/models/{sync_external_ads200_response.rb → webhook_payload_message_sent_message_sender.rb} +45 -31
  23. data/lib/late-sdk/version.rb +1 -1
  24. data/lib/late-sdk.rb +4 -1
  25. data/openapi.yaml +191 -37
  26. data/spec/api/accounts_api_spec.rb +13 -0
  27. data/spec/api/ad_campaigns_api_spec.rb +3 -1
  28. data/spec/api/ads_api_spec.rb +6 -13
  29. data/spec/api/connect_api_spec.rb +2 -2
  30. data/spec/models/disconnect_ads_request_spec.rb +40 -0
  31. data/spec/models/webhook_log_spec.rb +1 -1
  32. data/spec/models/{sync_external_ads200_response_spec.rb → webhook_payload_message_sent_message_sender_spec.rb} +10 -10
  33. data/spec/models/webhook_payload_message_sent_message_spec.rb +98 -0
  34. data/spec/models/webhook_payload_message_sent_spec.rb +70 -0
  35. data/spec/models/webhook_spec.rb +1 -1
  36. data/zernio-sdk-0.0.121.gem +0 -0
  37. metadata +756 -744
  38. data/docs/SyncExternalAds200Response.md +0 -24
  39. data/zernio-sdk-0.0.119.gem +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a6017bb3c967faecd4ac533acd584c76d525ab5b6a92f14dee6ac8890ebac30e
4
- data.tar.gz: b695c5b6eb8106f18e7995bf74f39e9bf774beb5a8c984ebed9c5d1746291a08
3
+ metadata.gz: 2d5f6b65fa188449e6b180747342cb2e8cb5062627774489b0abeb054486db92
4
+ data.tar.gz: 70ba187d5e62432e64059f6cef1931b28aa35e1be8a6497398f6108fdf885dda
5
5
  SHA512:
6
- metadata.gz: b34052ee82d690a8c148dfd1c2a1f8c4b4da983db0162c6e61b8b9e9fe94f48401deecd00c02586f034f58f368925353fe7907abb244b79a960516860d19dab1
7
- data.tar.gz: d78d2ca794476cbde6aa14e6a4bbc0233081bbd627c268a8b8fd7733108bdba4acd767de03dc1cd66adc34ba798b0bb5fc75947b7d4c692acfd8d93811787a27
6
+ metadata.gz: 1bc025598d5b060f3d4cedc9df0198d7886c0edb5101ea6df82afb4799c8610854a8fc313fd9a1254836d866c938efc43b88d76f60db9cedaa2777c083de1ccb
7
+ data.tar.gz: e6153a84560cf6386e0059045fad3c31b570ec0b03a0554de96b954556dc4508a5c9467dd5bb12ec4ca73997738e5ef8156cf4bf3300440a150da5f2e67381e7
data/README.md CHANGED
@@ -81,6 +81,7 @@ Class | Method | HTTP request | Description
81
81
  *Late::AccountSettingsApi* | [**set_messenger_menu**](docs/AccountSettingsApi.md#set_messenger_menu) | **PUT** /v1/accounts/{accountId}/messenger-menu | Set FB persistent menu
82
82
  *Late::AccountSettingsApi* | [**set_telegram_commands**](docs/AccountSettingsApi.md#set_telegram_commands) | **PUT** /v1/accounts/{accountId}/telegram-commands | Set TG bot commands
83
83
  *Late::AccountsApi* | [**delete_account**](docs/AccountsApi.md#delete_account) | **DELETE** /v1/accounts/{accountId} | Disconnect account
84
+ *Late::AccountsApi* | [**disconnect_ads**](docs/AccountsApi.md#disconnect_ads) | **POST** /v1/accounts/{accountId}/disconnect-ads | Disconnect ads from an account
84
85
  *Late::AccountsApi* | [**get_account_health**](docs/AccountsApi.md#get_account_health) | **GET** /v1/accounts/{accountId}/health | Check account health
85
86
  *Late::AccountsApi* | [**get_all_accounts_health**](docs/AccountsApi.md#get_all_accounts_health) | **GET** /v1/accounts/health | Check accounts health
86
87
  *Late::AccountsApi* | [**get_follower_stats**](docs/AccountsApi.md#get_follower_stats) | **GET** /v1/accounts/follower-stats | Get follower stats
@@ -103,7 +104,6 @@ Class | Method | HTTP request | Description
103
104
  *Late::AdsApi* | [**list_ad_accounts**](docs/AdsApi.md#list_ad_accounts) | **GET** /v1/ads/accounts | List ad accounts for a social account
104
105
  *Late::AdsApi* | [**list_ads**](docs/AdsApi.md#list_ads) | **GET** /v1/ads | List ads
105
106
  *Late::AdsApi* | [**search_ad_interests**](docs/AdsApi.md#search_ad_interests) | **GET** /v1/ads/interests | Search targeting interests
106
- *Late::AdsApi* | [**sync_external_ads**](docs/AdsApi.md#sync_external_ads) | **POST** /v1/ads/sync | Sync external ads from platform ad managers
107
107
  *Late::AdsApi* | [**update_ad**](docs/AdsApi.md#update_ad) | **PUT** /v1/ads/{adId} | Update ad (pause/resume, budget, targeting, name)
108
108
  *Late::AnalyticsApi* | [**get_analytics**](docs/AnalyticsApi.md#get_analytics) | **GET** /v1/analytics | Get post analytics
109
109
  *Late::AnalyticsApi* | [**get_best_time_to_post**](docs/AnalyticsApi.md#get_best_time_to_post) | **GET** /v1/analytics/best-time | Get best times to post
@@ -487,6 +487,7 @@ Class | Method | HTTP request | Description
487
487
  - [Late::DeleteInboxReviewReplyRequest](docs/DeleteInboxReviewReplyRequest.md)
488
488
  - [Late::DeleteQueueSlot200Response](docs/DeleteQueueSlot200Response.md)
489
489
  - [Late::DeleteWhatsAppGroupRequest](docs/DeleteWhatsAppGroupRequest.md)
490
+ - [Late::DisconnectAdsRequest](docs/DisconnectAdsRequest.md)
490
491
  - [Late::EditInboxMessage200Response](docs/EditInboxMessage200Response.md)
491
492
  - [Late::EditInboxMessage200ResponseData](docs/EditInboxMessage200ResponseData.md)
492
493
  - [Late::EditInboxMessageRequest](docs/EditInboxMessageRequest.md)
@@ -931,7 +932,6 @@ Class | Method | HTTP request | Description
931
932
  - [Late::SnapchatPlatformData](docs/SnapchatPlatformData.md)
932
933
  - [Late::SocialAccount](docs/SocialAccount.md)
933
934
  - [Late::SocialAccountProfileId](docs/SocialAccountProfileId.md)
934
- - [Late::SyncExternalAds200Response](docs/SyncExternalAds200Response.md)
935
935
  - [Late::TelegramPlatformData](docs/TelegramPlatformData.md)
936
936
  - [Late::TestWebhookRequest](docs/TestWebhookRequest.md)
937
937
  - [Late::ThreadsPlatformData](docs/ThreadsPlatformData.md)
@@ -1070,6 +1070,9 @@ Class | Method | HTTP request | Description
1070
1070
  - [Late::WebhookPayloadMessageMessageSender](docs/WebhookPayloadMessageMessageSender.md)
1071
1071
  - [Late::WebhookPayloadMessageMessageSenderInstagramProfile](docs/WebhookPayloadMessageMessageSenderInstagramProfile.md)
1072
1072
  - [Late::WebhookPayloadMessageMetadata](docs/WebhookPayloadMessageMetadata.md)
1073
+ - [Late::WebhookPayloadMessageSent](docs/WebhookPayloadMessageSent.md)
1074
+ - [Late::WebhookPayloadMessageSentMessage](docs/WebhookPayloadMessageSentMessage.md)
1075
+ - [Late::WebhookPayloadMessageSentMessageSender](docs/WebhookPayloadMessageSentMessageSender.md)
1073
1076
  - [Late::WebhookPayloadPost](docs/WebhookPayloadPost.md)
1074
1077
  - [Late::WebhookPayloadPostPost](docs/WebhookPayloadPostPost.md)
1075
1078
  - [Late::WebhookPayloadPostPostPlatformsInner](docs/WebhookPayloadPostPostPlatformsInner.md)
data/docs/AccountsApi.md CHANGED
@@ -5,6 +5,7 @@ All URIs are relative to *https://zernio.com/api*
5
5
  | Method | HTTP request | Description |
6
6
  | ------ | ------------ | ----------- |
7
7
  | [**delete_account**](AccountsApi.md#delete_account) | **DELETE** /v1/accounts/{accountId} | Disconnect account |
8
+ | [**disconnect_ads**](AccountsApi.md#disconnect_ads) | **POST** /v1/accounts/{accountId}/disconnect-ads | Disconnect ads from an account |
8
9
  | [**get_account_health**](AccountsApi.md#get_account_health) | **GET** /v1/accounts/{accountId}/health | Check account health |
9
10
  | [**get_all_accounts_health**](AccountsApi.md#get_all_accounts_health) | **GET** /v1/accounts/health | Check accounts health |
10
11
  | [**get_follower_stats**](AccountsApi.md#get_follower_stats) | **GET** /v1/accounts/follower-stats | Get follower stats |
@@ -82,6 +83,77 @@ end
82
83
  - **Accept**: application/json
83
84
 
84
85
 
86
+ ## disconnect_ads
87
+
88
+ > <DeleteAccountGroup200Response> disconnect_ads(account_id, disconnect_ads_request)
89
+
90
+ Disconnect ads from an account
91
+
92
+ Disconnects ads from a social account without removing the posting connection. **Same-token platforms** (metaads, linkedinads, pinterestads): Sets an `adsOptOut` flag. The posting account and OAuth token are preserved. Reconnecting ads clears the flag. **Separate-token platforms** (tiktokads, xads): Clears the ads-specific metadata (marketing API tokens). The posting account stays intact. **Standalone platforms** (googleads): Do not use this endpoint. Use `DELETE /v1/accounts/{accountId}` instead, since Google Ads accounts are standalone.
93
+
94
+ ### Examples
95
+
96
+ ```ruby
97
+ require 'time'
98
+ require 'late-sdk'
99
+ # setup authorization
100
+ Late.configure do |config|
101
+ # Configure Bearer authorization (JWT): bearerAuth
102
+ config.access_token = 'YOUR_BEARER_TOKEN'
103
+ end
104
+
105
+ api_instance = Late::AccountsApi.new
106
+ account_id = 'account_id_example' # String | The SocialAccount ID (parent posting account for same-token/separate-token platforms)
107
+ disconnect_ads_request = Late::DisconnectAdsRequest.new({ads_platform: 'metaads'}) # DisconnectAdsRequest |
108
+
109
+ begin
110
+ # Disconnect ads from an account
111
+ result = api_instance.disconnect_ads(account_id, disconnect_ads_request)
112
+ p result
113
+ rescue Late::ApiError => e
114
+ puts "Error when calling AccountsApi->disconnect_ads: #{e}"
115
+ end
116
+ ```
117
+
118
+ #### Using the disconnect_ads_with_http_info variant
119
+
120
+ This returns an Array which contains the response data, status code and headers.
121
+
122
+ > <Array(<DeleteAccountGroup200Response>, Integer, Hash)> disconnect_ads_with_http_info(account_id, disconnect_ads_request)
123
+
124
+ ```ruby
125
+ begin
126
+ # Disconnect ads from an account
127
+ data, status_code, headers = api_instance.disconnect_ads_with_http_info(account_id, disconnect_ads_request)
128
+ p status_code # => 2xx
129
+ p headers # => { ... }
130
+ p data # => <DeleteAccountGroup200Response>
131
+ rescue Late::ApiError => e
132
+ puts "Error when calling AccountsApi->disconnect_ads_with_http_info: #{e}"
133
+ end
134
+ ```
135
+
136
+ ### Parameters
137
+
138
+ | Name | Type | Description | Notes |
139
+ | ---- | ---- | ----------- | ----- |
140
+ | **account_id** | **String** | The SocialAccount ID (parent posting account for same-token/separate-token platforms) | |
141
+ | **disconnect_ads_request** | [**DisconnectAdsRequest**](DisconnectAdsRequest.md) | | |
142
+
143
+ ### Return type
144
+
145
+ [**DeleteAccountGroup200Response**](DeleteAccountGroup200Response.md)
146
+
147
+ ### Authorization
148
+
149
+ [bearerAuth](../README.md#bearerAuth)
150
+
151
+ ### HTTP request headers
152
+
153
+ - **Content-Type**: application/json
154
+ - **Accept**: application/json
155
+
156
+
85
157
  ## get_account_health
86
158
 
87
159
  > <GetAccountHealth200Response> get_account_health(account_id)
@@ -15,7 +15,7 @@ All URIs are relative to *https://zernio.com/api*
15
15
 
16
16
  Get nested campaign/ad-set/ad tree
17
17
 
18
- Returns a nested Campaign > Ad Set > Ad hierarchy with rolled-up metrics at each level. Uses a two-stage aggregation: ads are grouped into ad sets, then ad sets into campaigns. Pagination is at the campaign level. Ads without a campaign or ad set ID are grouped into synthetic \"Ungrouped\" buckets.
18
+ Returns a nested Campaign > Ad Set > Ad hierarchy with rolled-up metrics at each level. Uses a two-stage aggregation: ads are grouped into ad sets, then ad sets into campaigns. Metrics are computed over an optional date range, then rolled up from ad level to ad set and campaign levels. Pagination is at the campaign level. Ads without a campaign or ad set ID are grouped into synthetic \"Ungrouped\" buckets. If no date range is provided, defaults to the last 90 days. Date range is capped at 90 days max.
19
19
 
20
20
  ### Examples
21
21
 
@@ -37,7 +37,9 @@ opts = {
37
37
  status: 'active', # String | Filter by derived campaign status (post-aggregation)
38
38
  ad_account_id: 'ad_account_id_example', # String | Platform ad account ID
39
39
  account_id: 'account_id_example', # String | Social account ID
40
- profile_id: 'profile_id_example' # String | Profile ID
40
+ profile_id: 'profile_id_example', # String | Profile ID
41
+ from_date: Date.parse('2013-10-20'), # Date | Start of metrics date range (YYYY-MM-DD). Defaults to 90 days ago.
42
+ to_date: Date.parse('2013-10-20') # Date | End of metrics date range (YYYY-MM-DD). Defaults to today. Max 90-day range.
41
43
  }
42
44
 
43
45
  begin
@@ -79,6 +81,8 @@ end
79
81
  | **ad_account_id** | **String** | Platform ad account ID | [optional] |
80
82
  | **account_id** | **String** | Social account ID | [optional] |
81
83
  | **profile_id** | **String** | Profile ID | [optional] |
84
+ | **from_date** | **Date** | Start of metrics date range (YYYY-MM-DD). Defaults to 90 days ago. | [optional] |
85
+ | **to_date** | **Date** | End of metrics date range (YYYY-MM-DD). Defaults to today. Max 90-day range. | [optional] |
82
86
 
83
87
  ### Return type
84
88
 
data/docs/AdsApi.md CHANGED
@@ -12,7 +12,6 @@ All URIs are relative to *https://zernio.com/api*
12
12
  | [**list_ad_accounts**](AdsApi.md#list_ad_accounts) | **GET** /v1/ads/accounts | List ad accounts for a social account |
13
13
  | [**list_ads**](AdsApi.md#list_ads) | **GET** /v1/ads | List ads |
14
14
  | [**search_ad_interests**](AdsApi.md#search_ad_interests) | **GET** /v1/ads/interests | Search targeting interests |
15
- | [**sync_external_ads**](AdsApi.md#sync_external_ads) | **POST** /v1/ads/sync | Sync external ads from platform ad managers |
16
15
  | [**update_ad**](AdsApi.md#update_ad) | **PUT** /v1/ads/{adId} | Update ad (pause/resume, budget, targeting, name) |
17
16
 
18
17
 
@@ -296,7 +295,7 @@ end
296
295
 
297
296
  Get ad analytics with daily breakdown
298
297
 
299
- Returns real-time analytics from the platform API (not cached). Includes summary metrics, daily breakdown, and optional demographic breakdowns (Meta and TikTok only).
298
+ Returns detailed performance analytics for an ad. Includes summary metrics, a daily timeline over the requested date range, and optional demographic breakdowns (Meta and TikTok only). If no date range is provided, defaults to the last 90 days. Date range is capped at 90 days max.
300
299
 
301
300
  ### Examples
302
301
 
@@ -312,6 +311,8 @@ end
312
311
  api_instance = Late::AdsApi.new
313
312
  ad_id = 'ad_id_example' # String |
314
313
  opts = {
314
+ from_date: Date.parse('2013-10-20'), # Date | Start of date range (YYYY-MM-DD). Defaults to 90 days ago.
315
+ to_date: Date.parse('2013-10-20'), # Date | End of date range (YYYY-MM-DD). Defaults to today. Max 90-day range.
315
316
  breakdowns: 'breakdowns_example' # String | Comma-separated breakdown dimensions. Meta: age, gender, country, publisher_platform, device_platform, region. TikTok: gender, age, country_code, platform, ac, language.
316
317
  }
317
318
 
@@ -347,6 +348,8 @@ end
347
348
  | Name | Type | Description | Notes |
348
349
  | ---- | ---- | ----------- | ----- |
349
350
  | **ad_id** | **String** | | |
351
+ | **from_date** | **Date** | Start of date range (YYYY-MM-DD). Defaults to 90 days ago. | [optional] |
352
+ | **to_date** | **Date** | End of date range (YYYY-MM-DD). Defaults to today. Max 90-day range. | [optional] |
350
353
  | **breakdowns** | **String** | Comma-separated breakdown dimensions. Meta: age, gender, country, publisher_platform, device_platform, region. TikTok: gender, age, country_code, platform, ac, language. | [optional] |
351
354
 
352
355
  ### Return type
@@ -438,7 +441,7 @@ end
438
441
 
439
442
  List ads
440
443
 
441
- Returns a paginated list of ads with cached metrics. Use `source=all` to include externally-synced ads from platform ad managers.
444
+ Returns a paginated list of ads with metrics computed over an optional date range. Use `source=all` to include externally-synced ads from platform ad managers. If no date range is provided, defaults to the last 90 days. Date range is capped at 90 days max.
442
445
 
443
446
  ### Examples
444
447
 
@@ -460,7 +463,9 @@ opts = {
460
463
  platform: 'facebook', # String |
461
464
  account_id: 'account_id_example', # String | Social account ID
462
465
  profile_id: 'profile_id_example', # String | Profile ID
463
- campaign_id: 'campaign_id_example' # String | Platform campaign ID (filter ads within a campaign)
466
+ campaign_id: 'campaign_id_example', # String | Platform campaign ID (filter ads within a campaign)
467
+ from_date: Date.parse('2013-10-20'), # Date | Start of metrics date range (YYYY-MM-DD). Defaults to 90 days ago.
468
+ to_date: Date.parse('2013-10-20') # Date | End of metrics date range (YYYY-MM-DD). Defaults to today. Max 90-day range.
464
469
  }
465
470
 
466
471
  begin
@@ -502,6 +507,8 @@ end
502
507
  | **account_id** | **String** | Social account ID | [optional] |
503
508
  | **profile_id** | **String** | Profile ID | [optional] |
504
509
  | **campaign_id** | **String** | Platform campaign ID (filter ads within a campaign) | [optional] |
510
+ | **from_date** | **Date** | Start of metrics date range (YYYY-MM-DD). Defaults to 90 days ago. | [optional] |
511
+ | **to_date** | **Date** | End of metrics date range (YYYY-MM-DD). Defaults to today. Max 90-day range. | [optional] |
505
512
 
506
513
  ### Return type
507
514
 
@@ -588,72 +595,6 @@ end
588
595
  - **Accept**: application/json
589
596
 
590
597
 
591
- ## sync_external_ads
592
-
593
- > <SyncExternalAds200Response> sync_external_ads
594
-
595
- Sync external ads from platform ad managers
596
-
597
- Discovers and imports ads created outside Zernio (e.g. in Meta Ads Manager, Google Ads). Upserts new ads and updates metrics/status for existing ones. Also runs automatically every 30 minutes.
598
-
599
- ### Examples
600
-
601
- ```ruby
602
- require 'time'
603
- require 'late-sdk'
604
- # setup authorization
605
- Late.configure do |config|
606
- # Configure Bearer authorization (JWT): bearerAuth
607
- config.access_token = 'YOUR_BEARER_TOKEN'
608
- end
609
-
610
- api_instance = Late::AdsApi.new
611
-
612
- begin
613
- # Sync external ads from platform ad managers
614
- result = api_instance.sync_external_ads
615
- p result
616
- rescue Late::ApiError => e
617
- puts "Error when calling AdsApi->sync_external_ads: #{e}"
618
- end
619
- ```
620
-
621
- #### Using the sync_external_ads_with_http_info variant
622
-
623
- This returns an Array which contains the response data, status code and headers.
624
-
625
- > <Array(<SyncExternalAds200Response>, Integer, Hash)> sync_external_ads_with_http_info
626
-
627
- ```ruby
628
- begin
629
- # Sync external ads from platform ad managers
630
- data, status_code, headers = api_instance.sync_external_ads_with_http_info
631
- p status_code # => 2xx
632
- p headers # => { ... }
633
- p data # => <SyncExternalAds200Response>
634
- rescue Late::ApiError => e
635
- puts "Error when calling AdsApi->sync_external_ads_with_http_info: #{e}"
636
- end
637
- ```
638
-
639
- ### Parameters
640
-
641
- This endpoint does not need any parameter.
642
-
643
- ### Return type
644
-
645
- [**SyncExternalAds200Response**](SyncExternalAds200Response.md)
646
-
647
- ### Authorization
648
-
649
- [bearerAuth](../README.md#bearerAuth)
650
-
651
- ### HTTP request headers
652
-
653
- - **Content-Type**: Not defined
654
- - **Accept**: application/json
655
-
656
-
657
598
  ## update_ad
658
599
 
659
600
  > <UpdateAd200Response> update_ad(ad_id, update_ad_request)
data/docs/ConnectApi.md CHANGED
@@ -113,7 +113,7 @@ end
113
113
 
114
114
  Connect ads for a platform
115
115
 
116
- Unified ads connection endpoint. Handles all platforms through a single route: **Same-token platforms** (facebook, instagram, linkedin): If a posting account already exists, returns `alreadyConnected: true` immediately (no extra OAuth needed). If not, starts the normal OAuth flow, and the resulting account supports both posting and ads. **Separate-token platforms** (tiktok, twitter, pinterest): Requires an existing posting account (`accountId` param). If ads are already connected, returns `alreadyConnected: true`. Otherwise, starts the platform-specific marketing API OAuth flow. **Ads-only platforms** (googleads): If a Google Ads account exists, returns `alreadyConnected: true`. Otherwise, starts the Google Ads OAuth flow. Use the `adsStatus` field from `GET /v1/accounts` to check which accounts need ads connection.
116
+ Unified ads connection endpoint. Handles all platforms through a single route: **Same-token platforms** (facebook, instagram, linkedin, pinterest): If a posting account already exists, returns `alreadyConnected: true` immediately (no extra OAuth needed). If not, starts the normal OAuth flow, and the resulting account supports both posting and ads. **Separate-token platforms** (tiktok, twitter): Requires an existing posting account (`accountId` param). If ads are already connected, returns `alreadyConnected: true`. Otherwise, starts the platform-specific marketing API OAuth flow. **Ads-only platforms** (googleads): If a Google Ads account exists, returns `alreadyConnected: true`. Otherwise, starts the Google Ads OAuth flow. Use the `adsStatus` field from `GET /v1/accounts` to check which accounts need ads connection.
117
117
 
118
118
  ### Examples
119
119
 
@@ -130,7 +130,7 @@ api_instance = Late::ConnectApi.new
130
130
  platform = 'facebook' # String | Platform to connect ads for. Only platforms with ads support are accepted.
131
131
  profile_id = 'profile_id_example' # String | Your Zernio profile ID
132
132
  opts = {
133
- account_id: 'account_id_example', # String | Existing SocialAccount ID. Required for separate-token platforms (tiktok, twitter, pinterest). Ignored for same-token and ads-only platforms.
133
+ account_id: 'account_id_example', # String | Existing SocialAccount ID. Required for separate-token platforms (tiktok, twitter). Ignored for same-token and ads-only platforms.
134
134
  redirect_url: 'redirect_url_example', # String | Custom redirect URL after OAuth completes (same-token platforms only)
135
135
  headless: true # Boolean | Enable headless mode (same-token platforms only)
136
136
  }
@@ -168,7 +168,7 @@ end
168
168
  | ---- | ---- | ----------- | ----- |
169
169
  | **platform** | **String** | Platform to connect ads for. Only platforms with ads support are accepted. | |
170
170
  | **profile_id** | **String** | Your Zernio profile ID | |
171
- | **account_id** | **String** | Existing SocialAccount ID. Required for separate-token platforms (tiktok, twitter, pinterest). Ignored for same-token and ads-only platforms. | [optional] |
171
+ | **account_id** | **String** | Existing SocialAccount ID. Required for separate-token platforms (tiktok, twitter). Ignored for same-token and ads-only platforms. | [optional] |
172
172
  | **redirect_url** | **String** | Custom redirect URL after OAuth completes (same-token platforms only) | [optional] |
173
173
  | **headless** | **Boolean** | Enable headless mode (same-token platforms only) | [optional][default to false] |
174
174
 
@@ -0,0 +1,18 @@
1
+ # Late::DisconnectAdsRequest
2
+
3
+ ## Properties
4
+
5
+ | Name | Type | Description | Notes |
6
+ | ---- | ---- | ----------- | ----- |
7
+ | **ads_platform** | **String** | The ads platform to disconnect | |
8
+
9
+ ## Example
10
+
11
+ ```ruby
12
+ require 'late-sdk'
13
+
14
+ instance = Late::DisconnectAdsRequest.new(
15
+ ads_platform: null
16
+ )
17
+ ```
18
+
@@ -8,6 +8,7 @@ All URIs are relative to *https://zernio.com/api*
8
8
  | [**on_account_disconnected**](WebhookEventsApi.md#on_account_disconnected) | **POST** /account.disconnected | Account disconnected event |
9
9
  | [**on_comment_received**](WebhookEventsApi.md#on_comment_received) | **POST** /comment.received | Comment received event |
10
10
  | [**on_message_received**](WebhookEventsApi.md#on_message_received) | **POST** /message.received | Message received event |
11
+ | [**on_message_sent**](WebhookEventsApi.md#on_message_sent) | **POST** /message.sent | Message sent event |
11
12
  | [**on_post_cancelled**](WebhookEventsApi.md#on_post_cancelled) | **POST** /post.cancelled | Post cancelled event |
12
13
  | [**on_post_failed**](WebhookEventsApi.md#on_post_failed) | **POST** /post.failed | Post failed event |
13
14
  | [**on_post_partial**](WebhookEventsApi.md#on_post_partial) | **POST** /post.partial | Post partial event |
@@ -289,6 +290,74 @@ nil (empty response body)
289
290
  - **Accept**: Not defined
290
291
 
291
292
 
293
+ ## on_message_sent
294
+
295
+ > on_message_sent(webhook_payload_message_sent)
296
+
297
+ Message sent event
298
+
299
+ Fired when a message is sent via the API.
300
+
301
+ ### Examples
302
+
303
+ ```ruby
304
+ require 'time'
305
+ require 'late-sdk'
306
+ # setup authorization
307
+ Late.configure do |config|
308
+ # Configure Bearer authorization (JWT): bearerAuth
309
+ config.access_token = 'YOUR_BEARER_TOKEN'
310
+ end
311
+
312
+ api_instance = Late::WebhookEventsApi.new
313
+ webhook_payload_message_sent = # WebhookPayloadMessageSent |
314
+
315
+ begin
316
+ # Message sent event
317
+ api_instance.on_message_sent(webhook_payload_message_sent)
318
+ rescue Late::ApiError => e
319
+ puts "Error when calling WebhookEventsApi->on_message_sent: #{e}"
320
+ end
321
+ ```
322
+
323
+ #### Using the on_message_sent_with_http_info variant
324
+
325
+ This returns an Array which contains the response data (`nil` in this case), status code and headers.
326
+
327
+ > <Array(nil, Integer, Hash)> on_message_sent_with_http_info(webhook_payload_message_sent)
328
+
329
+ ```ruby
330
+ begin
331
+ # Message sent event
332
+ data, status_code, headers = api_instance.on_message_sent_with_http_info(webhook_payload_message_sent)
333
+ p status_code # => 2xx
334
+ p headers # => { ... }
335
+ p data # => nil
336
+ rescue Late::ApiError => e
337
+ puts "Error when calling WebhookEventsApi->on_message_sent_with_http_info: #{e}"
338
+ end
339
+ ```
340
+
341
+ ### Parameters
342
+
343
+ | Name | Type | Description | Notes |
344
+ | ---- | ---- | ----------- | ----- |
345
+ | **webhook_payload_message_sent** | [**WebhookPayloadMessageSent**](WebhookPayloadMessageSent.md) | | |
346
+
347
+ ### Return type
348
+
349
+ nil (empty response body)
350
+
351
+ ### Authorization
352
+
353
+ [bearerAuth](../README.md#bearerAuth)
354
+
355
+ ### HTTP request headers
356
+
357
+ - **Content-Type**: application/json
358
+ - **Accept**: Not defined
359
+
360
+
292
361
  ## on_post_cancelled
293
362
 
294
363
  > on_post_cancelled(webhook_payload_post)
@@ -0,0 +1,28 @@
1
+ # Late::WebhookPayloadMessageSent
2
+
3
+ ## Properties
4
+
5
+ | Name | Type | Description | Notes |
6
+ | ---- | ---- | ----------- | ----- |
7
+ | **id** | **String** | Stable webhook event ID | |
8
+ | **event** | **String** | | |
9
+ | **message** | [**WebhookPayloadMessageSentMessage**](WebhookPayloadMessageSentMessage.md) | | |
10
+ | **conversation** | [**WebhookPayloadMessageConversation**](WebhookPayloadMessageConversation.md) | | |
11
+ | **account** | [**WebhookPayloadMessageAccount**](WebhookPayloadMessageAccount.md) | | |
12
+ | **timestamp** | **Time** | | |
13
+
14
+ ## Example
15
+
16
+ ```ruby
17
+ require 'late-sdk'
18
+
19
+ instance = Late::WebhookPayloadMessageSent.new(
20
+ id: null,
21
+ event: null,
22
+ message: null,
23
+ conversation: null,
24
+ account: null,
25
+ timestamp: null
26
+ )
27
+ ```
28
+
@@ -0,0 +1,36 @@
1
+ # Late::WebhookPayloadMessageSentMessage
2
+
3
+ ## Properties
4
+
5
+ | Name | Type | Description | Notes |
6
+ | ---- | ---- | ----------- | ----- |
7
+ | **id** | **String** | Internal message ID | |
8
+ | **conversation_id** | **String** | Internal conversation ID | |
9
+ | **platform** | **String** | | |
10
+ | **platform_message_id** | **String** | Platform&#39;s message ID | |
11
+ | **direction** | **String** | | |
12
+ | **text** | **String** | Message text content | |
13
+ | **attachments** | [**Array&lt;WebhookPayloadMessageMessageAttachmentsInner&gt;**](WebhookPayloadMessageMessageAttachmentsInner.md) | | |
14
+ | **sender** | [**WebhookPayloadMessageSentMessageSender**](WebhookPayloadMessageSentMessageSender.md) | | |
15
+ | **sent_at** | **Time** | | |
16
+ | **is_read** | **Boolean** | | |
17
+
18
+ ## Example
19
+
20
+ ```ruby
21
+ require 'late-sdk'
22
+
23
+ instance = Late::WebhookPayloadMessageSentMessage.new(
24
+ id: null,
25
+ conversation_id: null,
26
+ platform: null,
27
+ platform_message_id: null,
28
+ direction: null,
29
+ text: null,
30
+ attachments: null,
31
+ sender: null,
32
+ sent_at: null,
33
+ is_read: null
34
+ )
35
+ ```
36
+
@@ -0,0 +1,24 @@
1
+ # Late::WebhookPayloadMessageSentMessageSender
2
+
3
+ ## Properties
4
+
5
+ | Name | Type | Description | Notes |
6
+ | ---- | ---- | ----------- | ----- |
7
+ | **id** | **String** | | |
8
+ | **name** | **String** | | [optional] |
9
+ | **username** | **String** | | [optional] |
10
+ | **picture** | **String** | | [optional] |
11
+
12
+ ## Example
13
+
14
+ ```ruby
15
+ require 'late-sdk'
16
+
17
+ instance = Late::WebhookPayloadMessageSentMessageSender.new(
18
+ id: null,
19
+ name: null,
20
+ username: null,
21
+ picture: null
22
+ )
23
+ ```
24
+
@@ -82,6 +82,80 @@ module Late
82
82
  return data, status_code, headers
83
83
  end
84
84
 
85
+ # Disconnect ads from an account
86
+ # Disconnects ads from a social account without removing the posting connection. **Same-token platforms** (metaads, linkedinads, pinterestads): Sets an `adsOptOut` flag. The posting account and OAuth token are preserved. Reconnecting ads clears the flag. **Separate-token platforms** (tiktokads, xads): Clears the ads-specific metadata (marketing API tokens). The posting account stays intact. **Standalone platforms** (googleads): Do not use this endpoint. Use `DELETE /v1/accounts/{accountId}` instead, since Google Ads accounts are standalone.
87
+ # @param account_id [String] The SocialAccount ID (parent posting account for same-token/separate-token platforms)
88
+ # @param disconnect_ads_request [DisconnectAdsRequest]
89
+ # @param [Hash] opts the optional parameters
90
+ # @return [DeleteAccountGroup200Response]
91
+ def disconnect_ads(account_id, disconnect_ads_request, opts = {})
92
+ data, _status_code, _headers = disconnect_ads_with_http_info(account_id, disconnect_ads_request, opts)
93
+ data
94
+ end
95
+
96
+ # Disconnect ads from an account
97
+ # Disconnects ads from a social account without removing the posting connection. **Same-token platforms** (metaads, linkedinads, pinterestads): Sets an &#x60;adsOptOut&#x60; flag. The posting account and OAuth token are preserved. Reconnecting ads clears the flag. **Separate-token platforms** (tiktokads, xads): Clears the ads-specific metadata (marketing API tokens). The posting account stays intact. **Standalone platforms** (googleads): Do not use this endpoint. Use &#x60;DELETE /v1/accounts/{accountId}&#x60; instead, since Google Ads accounts are standalone.
98
+ # @param account_id [String] The SocialAccount ID (parent posting account for same-token/separate-token platforms)
99
+ # @param disconnect_ads_request [DisconnectAdsRequest]
100
+ # @param [Hash] opts the optional parameters
101
+ # @return [Array<(DeleteAccountGroup200Response, Integer, Hash)>] DeleteAccountGroup200Response data, response status code and response headers
102
+ def disconnect_ads_with_http_info(account_id, disconnect_ads_request, opts = {})
103
+ if @api_client.config.debugging
104
+ @api_client.config.logger.debug 'Calling API: AccountsApi.disconnect_ads ...'
105
+ end
106
+ # verify the required parameter 'account_id' is set
107
+ if @api_client.config.client_side_validation && account_id.nil?
108
+ fail ArgumentError, "Missing the required parameter 'account_id' when calling AccountsApi.disconnect_ads"
109
+ end
110
+ # verify the required parameter 'disconnect_ads_request' is set
111
+ if @api_client.config.client_side_validation && disconnect_ads_request.nil?
112
+ fail ArgumentError, "Missing the required parameter 'disconnect_ads_request' when calling AccountsApi.disconnect_ads"
113
+ end
114
+ # resource path
115
+ local_var_path = '/v1/accounts/{accountId}/disconnect-ads'.sub('{' + 'accountId' + '}', CGI.escape(account_id.to_s))
116
+
117
+ # query parameters
118
+ query_params = opts[:query_params] || {}
119
+
120
+ # header parameters
121
+ header_params = opts[:header_params] || {}
122
+ # HTTP header 'Accept' (if needed)
123
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
124
+ # HTTP header 'Content-Type'
125
+ content_type = @api_client.select_header_content_type(['application/json'])
126
+ if !content_type.nil?
127
+ header_params['Content-Type'] = content_type
128
+ end
129
+
130
+ # form parameters
131
+ form_params = opts[:form_params] || {}
132
+
133
+ # http body (model)
134
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(disconnect_ads_request)
135
+
136
+ # return_type
137
+ return_type = opts[:debug_return_type] || 'DeleteAccountGroup200Response'
138
+
139
+ # auth_names
140
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
141
+
142
+ new_options = opts.merge(
143
+ :operation => :"AccountsApi.disconnect_ads",
144
+ :header_params => header_params,
145
+ :query_params => query_params,
146
+ :form_params => form_params,
147
+ :body => post_body,
148
+ :auth_names => auth_names,
149
+ :return_type => return_type
150
+ )
151
+
152
+ data, status_code, headers = @api_client.call_api(:POST, local_var_path, new_options)
153
+ if @api_client.config.debugging
154
+ @api_client.config.logger.debug "API called: AccountsApi#disconnect_ads\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
155
+ end
156
+ return data, status_code, headers
157
+ end
158
+
85
159
  # Check account health
86
160
  # Returns detailed health info for a specific account including token status, permissions, and recommendations.
87
161
  # @param account_id [String] The account ID to check
@@ -20,7 +20,7 @@ module Late
20
20
  @api_client = api_client
21
21
  end
22
22
  # Get nested campaign/ad-set/ad tree
23
- # Returns a nested Campaign > Ad Set > Ad hierarchy with rolled-up metrics at each level. Uses a two-stage aggregation: ads are grouped into ad sets, then ad sets into campaigns. Pagination is at the campaign level. Ads without a campaign or ad set ID are grouped into synthetic \"Ungrouped\" buckets.
23
+ # Returns a nested Campaign > Ad Set > Ad hierarchy with rolled-up metrics at each level. Uses a two-stage aggregation: ads are grouped into ad sets, then ad sets into campaigns. Metrics are computed over an optional date range, then rolled up from ad level to ad set and campaign levels. Pagination is at the campaign level. Ads without a campaign or ad set ID are grouped into synthetic \"Ungrouped\" buckets. If no date range is provided, defaults to the last 90 days. Date range is capped at 90 days max.
24
24
  # @param [Hash] opts the optional parameters
25
25
  # @option opts [Integer] :page Page number (1-based) (default to 1)
26
26
  # @option opts [Integer] :limit Campaigns per page (default to 20)
@@ -30,6 +30,8 @@ module Late
30
30
  # @option opts [String] :ad_account_id Platform ad account ID
31
31
  # @option opts [String] :account_id Social account ID
32
32
  # @option opts [String] :profile_id Profile ID
33
+ # @option opts [Date] :from_date Start of metrics date range (YYYY-MM-DD). Defaults to 90 days ago.
34
+ # @option opts [Date] :to_date End of metrics date range (YYYY-MM-DD). Defaults to today. Max 90-day range.
33
35
  # @return [GetAdTree200Response]
34
36
  def get_ad_tree(opts = {})
35
37
  data, _status_code, _headers = get_ad_tree_with_http_info(opts)
@@ -37,7 +39,7 @@ module Late
37
39
  end
38
40
 
39
41
  # Get nested campaign/ad-set/ad tree
40
- # Returns a nested Campaign &gt; Ad Set &gt; Ad hierarchy with rolled-up metrics at each level. Uses a two-stage aggregation: ads are grouped into ad sets, then ad sets into campaigns. Pagination is at the campaign level. Ads without a campaign or ad set ID are grouped into synthetic \&quot;Ungrouped\&quot; buckets.
42
+ # Returns a nested Campaign &gt; Ad Set &gt; Ad hierarchy with rolled-up metrics at each level. Uses a two-stage aggregation: ads are grouped into ad sets, then ad sets into campaigns. Metrics are computed over an optional date range, then rolled up from ad level to ad set and campaign levels. Pagination is at the campaign level. Ads without a campaign or ad set ID are grouped into synthetic \&quot;Ungrouped\&quot; buckets. If no date range is provided, defaults to the last 90 days. Date range is capped at 90 days max.
41
43
  # @param [Hash] opts the optional parameters
42
44
  # @option opts [Integer] :page Page number (1-based) (default to 1)
43
45
  # @option opts [Integer] :limit Campaigns per page (default to 20)
@@ -47,6 +49,8 @@ module Late
47
49
  # @option opts [String] :ad_account_id Platform ad account ID
48
50
  # @option opts [String] :account_id Social account ID
49
51
  # @option opts [String] :profile_id Profile ID
52
+ # @option opts [Date] :from_date Start of metrics date range (YYYY-MM-DD). Defaults to 90 days ago.
53
+ # @option opts [Date] :to_date End of metrics date range (YYYY-MM-DD). Defaults to today. Max 90-day range.
50
54
  # @return [Array<(GetAdTree200Response, Integer, Hash)>] GetAdTree200Response data, response status code and response headers
51
55
  def get_ad_tree_with_http_info(opts = {})
52
56
  if @api_client.config.debugging
@@ -89,6 +93,8 @@ module Late
89
93
  query_params[:'adAccountId'] = opts[:'ad_account_id'] if !opts[:'ad_account_id'].nil?
90
94
  query_params[:'accountId'] = opts[:'account_id'] if !opts[:'account_id'].nil?
91
95
  query_params[:'profileId'] = opts[:'profile_id'] if !opts[:'profile_id'].nil?
96
+ query_params[:'fromDate'] = opts[:'from_date'] if !opts[:'from_date'].nil?
97
+ query_params[:'toDate'] = opts[:'to_date'] if !opts[:'to_date'].nil?
92
98
 
93
99
  # header parameters
94
100
  header_params = opts[:header_params] || {}