late-sdk 0.0.52 → 0.0.53

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 (105) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +32 -0
  3. data/docs/AnalyticsListResponsePostsInner.md +1 -1
  4. data/docs/AnalyticsSinglePostResponse.md +7 -1
  5. data/docs/AnalyticsSinglePostResponseMediaItemsInner.md +22 -0
  6. data/docs/BookmarkPost200Response.md +24 -0
  7. data/docs/BookmarkPostRequest.md +20 -0
  8. data/docs/CommentsApi.md +2 -2
  9. data/docs/FollowUser200Response.md +26 -0
  10. data/docs/FollowUserRequest.md +20 -0
  11. data/docs/GMBLocationDetailsApi.md +4 -4
  12. data/docs/GbpFreeFormServiceItemLabel.md +20 -0
  13. data/docs/GbpUpdateFreeFormServiceItemLabel.md +20 -0
  14. data/docs/GetGoogleBusinessLocationDetails200Response.md +5 -1
  15. data/docs/GetGoogleBusinessLocationDetails200ResponseCategories.md +20 -0
  16. data/docs/GetGoogleBusinessLocationDetails200ResponseCategoriesAdditionalCategoriesInner.md +20 -0
  17. data/docs/GetGoogleBusinessLocationDetails200ResponseCategoriesPrimaryCategory.md +20 -0
  18. data/docs/GetGoogleBusinessLocationDetails200ResponseServiceItemsInner.md +22 -0
  19. data/docs/GetGoogleBusinessLocationDetails200ResponseServiceItemsInnerFreeFormServiceItem.md +20 -0
  20. data/docs/GetGoogleBusinessLocationDetails200ResponseServiceItemsInnerPrice.md +22 -0
  21. data/docs/GetGoogleBusinessLocationDetails200ResponseServiceItemsInnerStructuredServiceItem.md +20 -0
  22. data/docs/RemoveBookmark200Response.md +24 -0
  23. data/docs/RetweetPost200Response.md +24 -0
  24. data/docs/RetweetPostRequest.md +20 -0
  25. data/docs/TwitterEngagementApi.md +433 -0
  26. data/docs/UndoRetweet200Response.md +24 -0
  27. data/docs/UnfollowUser200Response.md +24 -0
  28. data/docs/UpdateGoogleBusinessLocationDetailsRequest.md +6 -2
  29. data/docs/UpdateGoogleBusinessLocationDetailsRequestCategories.md +20 -0
  30. data/docs/UpdateGoogleBusinessLocationDetailsRequestCategoriesAdditionalCategoriesInner.md +18 -0
  31. data/docs/UpdateGoogleBusinessLocationDetailsRequestCategoriesPrimaryCategory.md +18 -0
  32. data/docs/UpdateGoogleBusinessLocationDetailsRequestServiceItemsInner.md +22 -0
  33. data/docs/UpdateGoogleBusinessLocationDetailsRequestServiceItemsInnerFreeFormServiceItem.md +20 -0
  34. data/docs/UpdateGoogleBusinessLocationDetailsRequestServiceItemsInnerPrice.md +22 -0
  35. data/docs/UpdateGoogleBusinessLocationDetailsRequestServiceItemsInnerStructuredServiceItem.md +20 -0
  36. data/lib/late-sdk/api/comments_api.rb +4 -4
  37. data/lib/late-sdk/api/gmb_location_details_api.rb +6 -6
  38. data/lib/late-sdk/api/twitter_engagement_api.rb +439 -0
  39. data/lib/late-sdk/models/analytics_list_response_posts_inner.rb +4 -3
  40. data/lib/late-sdk/models/analytics_single_post_response.rb +68 -4
  41. data/lib/late-sdk/models/analytics_single_post_response_media_items_inner.rb +201 -0
  42. data/lib/late-sdk/models/bookmark_post200_response.rb +174 -0
  43. data/lib/late-sdk/models/bookmark_post_request.rb +192 -0
  44. data/lib/late-sdk/models/follow_user200_response.rb +184 -0
  45. data/lib/late-sdk/models/follow_user_request.rb +192 -0
  46. data/lib/late-sdk/models/gbp_free_form_service_item_label.rb +156 -0
  47. data/lib/late-sdk/models/gbp_update_free_form_service_item_label.rb +158 -0
  48. data/lib/late-sdk/models/get_google_business_location_details200_response.rb +25 -4
  49. data/lib/late-sdk/models/get_google_business_location_details200_response_categories.rb +159 -0
  50. data/lib/late-sdk/models/get_google_business_location_details200_response_categories_additional_categories_inner.rb +156 -0
  51. data/lib/late-sdk/models/get_google_business_location_details200_response_categories_primary_category.rb +158 -0
  52. data/lib/late-sdk/models/get_google_business_location_details200_response_service_items_inner.rb +165 -0
  53. data/lib/late-sdk/models/get_google_business_location_details200_response_service_items_inner_free_form_service_item.rb +156 -0
  54. data/lib/late-sdk/models/get_google_business_location_details200_response_service_items_inner_price.rb +165 -0
  55. data/lib/late-sdk/models/get_google_business_location_details200_response_service_items_inner_structured_service_item.rb +156 -0
  56. data/lib/late-sdk/models/remove_bookmark200_response.rb +174 -0
  57. data/lib/late-sdk/models/retweet_post200_response.rb +174 -0
  58. data/lib/late-sdk/models/retweet_post_request.rb +192 -0
  59. data/lib/late-sdk/models/undo_retweet200_response.rb +174 -0
  60. data/lib/late-sdk/models/unfollow_user200_response.rb +174 -0
  61. data/lib/late-sdk/models/update_google_business_location_details_request.rb +26 -5
  62. data/lib/late-sdk/models/update_google_business_location_details_request_categories.rb +159 -0
  63. data/lib/late-sdk/models/update_google_business_location_details_request_categories_additional_categories_inner.rb +148 -0
  64. data/lib/late-sdk/models/update_google_business_location_details_request_categories_primary_category.rb +148 -0
  65. data/lib/late-sdk/models/update_google_business_location_details_request_service_items_inner.rb +165 -0
  66. data/lib/late-sdk/models/update_google_business_location_details_request_service_items_inner_free_form_service_item.rb +158 -0
  67. data/lib/late-sdk/models/update_google_business_location_details_request_service_items_inner_price.rb +169 -0
  68. data/lib/late-sdk/models/update_google_business_location_details_request_service_items_inner_structured_service_item.rb +159 -0
  69. data/lib/late-sdk/version.rb +1 -1
  70. data/lib/late-sdk.rb +27 -0
  71. data/openapi.yaml +406 -29
  72. data/spec/api/comments_api_spec.rb +2 -2
  73. data/spec/api/gmb_location_details_api_spec.rb +3 -3
  74. data/spec/api/twitter_engagement_api_spec.rb +110 -0
  75. data/spec/models/analytics_list_response_posts_inner_spec.rb +1 -1
  76. data/spec/models/analytics_single_post_response_media_items_inner_spec.rb +52 -0
  77. data/spec/models/analytics_single_post_response_spec.rb +22 -0
  78. data/spec/models/bookmark_post200_response_spec.rb +54 -0
  79. data/spec/models/bookmark_post_request_spec.rb +42 -0
  80. data/spec/models/follow_user200_response_spec.rb +60 -0
  81. data/spec/models/follow_user_request_spec.rb +42 -0
  82. data/spec/models/gbp_free_form_service_item_label_spec.rb +42 -0
  83. data/spec/models/gbp_update_free_form_service_item_label_spec.rb +42 -0
  84. data/spec/models/get_google_business_location_details200_response_categories_additional_categories_inner_spec.rb +42 -0
  85. data/spec/models/get_google_business_location_details200_response_categories_primary_category_spec.rb +42 -0
  86. data/spec/models/get_google_business_location_details200_response_categories_spec.rb +42 -0
  87. data/spec/models/get_google_business_location_details200_response_service_items_inner_free_form_service_item_spec.rb +42 -0
  88. data/spec/models/get_google_business_location_details200_response_service_items_inner_price_spec.rb +48 -0
  89. data/spec/models/get_google_business_location_details200_response_service_items_inner_spec.rb +48 -0
  90. data/spec/models/get_google_business_location_details200_response_service_items_inner_structured_service_item_spec.rb +42 -0
  91. data/spec/models/get_google_business_location_details200_response_spec.rb +12 -0
  92. data/spec/models/remove_bookmark200_response_spec.rb +54 -0
  93. data/spec/models/retweet_post200_response_spec.rb +54 -0
  94. data/spec/models/retweet_post_request_spec.rb +42 -0
  95. data/spec/models/undo_retweet200_response_spec.rb +54 -0
  96. data/spec/models/unfollow_user200_response_spec.rb +54 -0
  97. data/spec/models/update_google_business_location_details_request_categories_additional_categories_inner_spec.rb +36 -0
  98. data/spec/models/update_google_business_location_details_request_categories_primary_category_spec.rb +36 -0
  99. data/spec/models/update_google_business_location_details_request_categories_spec.rb +42 -0
  100. data/spec/models/update_google_business_location_details_request_service_items_inner_free_form_service_item_spec.rb +42 -0
  101. data/spec/models/update_google_business_location_details_request_service_items_inner_price_spec.rb +48 -0
  102. data/spec/models/update_google_business_location_details_request_service_items_inner_spec.rb +48 -0
  103. data/spec/models/update_google_business_location_details_request_service_items_inner_structured_service_item_spec.rb +42 -0
  104. data/spec/models/update_google_business_location_details_request_spec.rb +12 -0
  105. metadata +110 -2
data/lib/late-sdk.rb CHANGED
@@ -29,9 +29,12 @@ require 'late-sdk/models/analytics_list_response'
29
29
  require 'late-sdk/models/analytics_list_response_posts_inner'
30
30
  require 'late-sdk/models/analytics_overview'
31
31
  require 'late-sdk/models/analytics_single_post_response'
32
+ require 'late-sdk/models/analytics_single_post_response_media_items_inner'
32
33
  require 'late-sdk/models/api_key'
33
34
  require 'late-sdk/models/api_key_profile_ids_inner'
34
35
  require 'late-sdk/models/bluesky_platform_data'
36
+ require 'late-sdk/models/bookmark_post200_response'
37
+ require 'late-sdk/models/bookmark_post_request'
35
38
  require 'late-sdk/models/bulk_delete_whats_app_contacts200_response'
36
39
  require 'late-sdk/models/bulk_delete_whats_app_contacts_request'
37
40
  require 'late-sdk/models/bulk_update_whats_app_contacts200_response'
@@ -116,6 +119,8 @@ require 'late-sdk/models/edit_inbox_message_request_reply_markup_keyboard_inner_
116
119
  require 'late-sdk/models/error_response'
117
120
  require 'late-sdk/models/expired'
118
121
  require 'late-sdk/models/facebook_platform_data'
122
+ require 'late-sdk/models/follow_user200_response'
123
+ require 'late-sdk/models/follow_user_request'
119
124
  require 'late-sdk/models/follower_stats_response'
120
125
  require 'late-sdk/models/food_menu'
121
126
  require 'late-sdk/models/food_menu_item'
@@ -123,8 +128,10 @@ require 'late-sdk/models/food_menu_item_attributes'
123
128
  require 'late-sdk/models/food_menu_item_options_inner'
124
129
  require 'late-sdk/models/food_menu_label'
125
130
  require 'late-sdk/models/food_menu_section'
131
+ require 'late-sdk/models/gbp_free_form_service_item_label'
126
132
  require 'late-sdk/models/gbp_special_hour_period'
127
133
  require 'late-sdk/models/gbp_special_hour_period_start_date'
134
+ require 'late-sdk/models/gbp_update_free_form_service_item_label'
128
135
  require 'late-sdk/models/get_account_health200_response'
129
136
  require 'late-sdk/models/get_account_health200_response_permissions'
130
137
  require 'late-sdk/models/get_account_health200_response_permissions_posting_inner'
@@ -157,10 +164,17 @@ require 'late-sdk/models/get_google_business_attributes200_response_attributes_i
157
164
  require 'late-sdk/models/get_google_business_attributes200_response_attributes_inner_repeated_enum_value'
158
165
  require 'late-sdk/models/get_google_business_food_menus200_response'
159
166
  require 'late-sdk/models/get_google_business_location_details200_response'
167
+ require 'late-sdk/models/get_google_business_location_details200_response_categories'
168
+ require 'late-sdk/models/get_google_business_location_details200_response_categories_additional_categories_inner'
169
+ require 'late-sdk/models/get_google_business_location_details200_response_categories_primary_category'
160
170
  require 'late-sdk/models/get_google_business_location_details200_response_phone_numbers'
161
171
  require 'late-sdk/models/get_google_business_location_details200_response_profile'
162
172
  require 'late-sdk/models/get_google_business_location_details200_response_regular_hours'
163
173
  require 'late-sdk/models/get_google_business_location_details200_response_regular_hours_periods_inner'
174
+ require 'late-sdk/models/get_google_business_location_details200_response_service_items_inner'
175
+ require 'late-sdk/models/get_google_business_location_details200_response_service_items_inner_free_form_service_item'
176
+ require 'late-sdk/models/get_google_business_location_details200_response_service_items_inner_price'
177
+ require 'late-sdk/models/get_google_business_location_details200_response_service_items_inner_structured_service_item'
164
178
  require 'late-sdk/models/get_google_business_location_details200_response_special_hours'
165
179
  require 'late-sdk/models/get_google_business_reviews200_response'
166
180
  require 'late-sdk/models/get_google_business_reviews200_response_reviews_inner'
@@ -373,6 +387,7 @@ require 'late-sdk/models/recycling_state'
373
387
  require 'late-sdk/models/reddit_platform_data'
374
388
  require 'late-sdk/models/release_whats_app_phone_number200_response'
375
389
  require 'late-sdk/models/release_whats_app_phone_number200_response_phone_number'
390
+ require 'late-sdk/models/remove_bookmark200_response'
376
391
  require 'late-sdk/models/remove_whats_app_broadcast_recipients200_response'
377
392
  require 'late-sdk/models/remove_whats_app_broadcast_recipients_request'
378
393
  require 'late-sdk/models/rename_whats_app_group200_response'
@@ -383,6 +398,8 @@ require 'late-sdk/models/reply_to_inbox_post_request'
383
398
  require 'late-sdk/models/reply_to_inbox_review200_response'
384
399
  require 'late-sdk/models/reply_to_inbox_review200_response_reply'
385
400
  require 'late-sdk/models/reply_to_inbox_review_request'
401
+ require 'late-sdk/models/retweet_post200_response'
402
+ require 'late-sdk/models/retweet_post_request'
386
403
  require 'late-sdk/models/schedule_whats_app_broadcast200_response'
387
404
  require 'late-sdk/models/schedule_whats_app_broadcast200_response_broadcast'
388
405
  require 'late-sdk/models/schedule_whats_app_broadcast_request'
@@ -443,6 +460,8 @@ require 'late-sdk/models/transcript_response'
443
460
  require 'late-sdk/models/transcript_segment'
444
461
  require 'late-sdk/models/twitter_platform_data'
445
462
  require 'late-sdk/models/twitter_platform_data_thread_items_inner'
463
+ require 'late-sdk/models/undo_retweet200_response'
464
+ require 'late-sdk/models/unfollow_user200_response'
446
465
  require 'late-sdk/models/unlike_inbox_comment200_response'
447
466
  require 'late-sdk/models/unpublish_post200_response'
448
467
  require 'late-sdk/models/unpublish_post_request'
@@ -462,9 +481,16 @@ require 'late-sdk/models/update_google_business_food_menus200_response'
462
481
  require 'late-sdk/models/update_google_business_food_menus_request'
463
482
  require 'late-sdk/models/update_google_business_location_details200_response'
464
483
  require 'late-sdk/models/update_google_business_location_details_request'
484
+ require 'late-sdk/models/update_google_business_location_details_request_categories'
485
+ require 'late-sdk/models/update_google_business_location_details_request_categories_additional_categories_inner'
486
+ require 'late-sdk/models/update_google_business_location_details_request_categories_primary_category'
465
487
  require 'late-sdk/models/update_google_business_location_details_request_profile'
466
488
  require 'late-sdk/models/update_google_business_location_details_request_regular_hours'
467
489
  require 'late-sdk/models/update_google_business_location_details_request_regular_hours_periods_inner'
490
+ require 'late-sdk/models/update_google_business_location_details_request_service_items_inner'
491
+ require 'late-sdk/models/update_google_business_location_details_request_service_items_inner_free_form_service_item'
492
+ require 'late-sdk/models/update_google_business_location_details_request_service_items_inner_price'
493
+ require 'late-sdk/models/update_google_business_location_details_request_service_items_inner_structured_service_item'
468
494
  require 'late-sdk/models/update_inbox_conversation200_response'
469
495
  require 'late-sdk/models/update_inbox_conversation200_response_data'
470
496
  require 'late-sdk/models/update_inbox_conversation_request'
@@ -572,6 +598,7 @@ require 'late-sdk/api/queue_api'
572
598
  require 'late-sdk/api/reddit_search_api'
573
599
  require 'late-sdk/api/reviews_api'
574
600
  require 'late-sdk/api/tools_api'
601
+ require 'late-sdk/api/twitter_engagement_api'
575
602
  require 'late-sdk/api/usage_api'
576
603
  require 'late-sdk/api/users_api'
577
604
  require 'late-sdk/api/validate_api'
data/openapi.yaml CHANGED
@@ -144,7 +144,7 @@ x-documentation:
144
144
 
145
145
  ## SDKs
146
146
 
147
- Official SDKs available for: [Node.js](https://www.npmjs.com/package/late), [Python](https://pypi.org/project/late), Go, Ruby, Java, PHP, .NET, and Rust.
147
+ Official SDKs available for: [Node.js](https://www.npmjs.com/package/@getlatedev/node), [Python](https://pypi.org/project/late-sdk), Go, Ruby, Java, PHP, .NET, and Rust.
148
148
 
149
149
  servers:
150
150
  - url: https://getlate.dev/api
@@ -195,6 +195,11 @@ tags:
195
195
  Unified inbox API for managing reviews on Facebook Pages and Google Business accounts.
196
196
  All endpoints aggregate data from multiple social accounts in a single API call.
197
197
  Requires Inbox addon.
198
+ - name: Twitter Engagement
199
+ description: |
200
+ X/Twitter-specific engagement endpoints for retweeting, bookmarking, and following.
201
+ All endpoints require an X API Basic tier ($200/mo) or higher. Users must reconnect their X account after upgrading to grant the required OAuth scopes.
202
+ Rate limits: 50 requests per 15-min window per user. Retweets share the 300/3hr creation limit with tweet creation.
198
203
  - name: Tools
199
204
  description: |
200
205
  Media download and utility tools. Available to paid plans only.
@@ -1784,6 +1789,17 @@ components:
1784
1789
  platform: { type: string }
1785
1790
  platformPostUrl: { type: string, format: uri }
1786
1791
  isExternal: { type: boolean }
1792
+ thumbnailUrl: { type: string, format: uri, nullable: true }
1793
+ mediaType: { type: string, enum: [image, video, carousel, text], nullable: true }
1794
+ mediaItems:
1795
+ type: array
1796
+ description: All media items for this post. Carousel posts contain one entry per slide.
1797
+ items:
1798
+ type: object
1799
+ properties:
1800
+ type: { type: string, enum: [image, video] }
1801
+ url: { type: string, format: uri, description: Direct URL to the media }
1802
+ thumbnail: { type: string, format: uri, description: Thumbnail URL (same as url for images) }
1787
1803
  AnalyticsListResponse:
1788
1804
  type: object
1789
1805
  properties:
@@ -1809,11 +1825,16 @@ components:
1809
1825
  platformPostUrl: { type: string, format: uri }
1810
1826
  isExternal: { type: boolean }
1811
1827
  thumbnailUrl: { type: string, format: uri }
1812
- mediaType: { type: string, enum: [image, video, gif, document] }
1828
+ mediaType: { type: string, enum: [image, video, gif, document, carousel, text] }
1813
1829
  mediaItems:
1814
1830
  type: array
1831
+ description: All media items for this post. Carousel posts contain one entry per slide.
1815
1832
  items:
1816
- $ref: '#/components/schemas/MediaItem'
1833
+ type: object
1834
+ properties:
1835
+ type: { type: string, enum: [image, video] }
1836
+ url: { type: string, format: uri, description: Direct URL to the media }
1837
+ thumbnail: { type: string, format: uri, description: Thumbnail URL (same as url for images) }
1817
1838
  pagination:
1818
1839
  $ref: '#/components/schemas/Pagination'
1819
1840
  accounts:
@@ -2982,6 +3003,12 @@ paths:
2982
3003
  platform: "twitter"
2983
3004
  platformPostUrl: "https://twitter.com/acmecorp/status/123456789"
2984
3005
  isExternal: false
3006
+ thumbnailUrl: "https://storage.example.com/image.jpg"
3007
+ mediaType: "image"
3008
+ mediaItems:
3009
+ - type: "image"
3010
+ url: "https://storage.example.com/image.jpg"
3011
+ thumbnail: "https://storage.example.com/image.jpg"
2985
3012
  postList:
2986
3013
  summary: Paginated analytics list
2987
3014
  description: |
@@ -3018,7 +3045,14 @@ paths:
3018
3045
  platformPostUrl: "https://www.instagram.com/reel/ABC123xyz/"
3019
3046
  isExternal: true
3020
3047
  thumbnailUrl: "https://storage.example.com/thumb.jpg"
3021
- mediaType: "video"
3048
+ mediaType: "carousel"
3049
+ mediaItems:
3050
+ - type: "image"
3051
+ url: "https://storage.example.com/slide1.jpg"
3052
+ thumbnail: "https://storage.example.com/slide1.jpg"
3053
+ - type: "image"
3054
+ url: "https://storage.example.com/slide2.jpg"
3055
+ thumbnail: "https://storage.example.com/slide2.jpg"
3022
3056
  pagination:
3023
3057
  page: 1
3024
3058
  limit: 50
@@ -6363,7 +6397,7 @@ paths:
6363
6397
  operationId: getGoogleBusinessLocationDetails
6364
6398
  tags: [GMB Location Details]
6365
6399
  summary: Get location details
6366
- description: Returns detailed GBP location info (hours, description, phone, website, categories). Use readMask to request specific fields.
6400
+ description: Returns detailed GBP location info (hours, description, phone, website, categories, services). Use readMask to request specific fields.
6367
6401
  parameters:
6368
6402
  - name: accountId
6369
6403
  in: path
@@ -6378,7 +6412,7 @@ paths:
6378
6412
  in: query
6379
6413
  required: false
6380
6414
  schema: { type: string }
6381
- description: "Comma-separated fields to return. Available: name, title, phoneNumbers, categories, storefrontAddress, websiteUri, regularHours, specialHours, serviceArea, profile, openInfo, metadata, moreHours."
6415
+ description: "Comma-separated fields to return. Available: name, title, phoneNumbers, categories, storefrontAddress, websiteUri, regularHours, specialHours, serviceArea, serviceItems, profile, openInfo, metadata, moreHours."
6382
6416
  security:
6383
6417
  - bearerAuth: []
6384
6418
  responses:
@@ -6428,6 +6462,48 @@ paths:
6428
6462
  properties:
6429
6463
  primaryPhone: { type: string }
6430
6464
  additionalPhones: { type: array, items: { type: string } }
6465
+ categories:
6466
+ type: object
6467
+ description: "Business categories (returned when readMask includes 'categories')"
6468
+ properties:
6469
+ primaryCategory:
6470
+ type: object
6471
+ properties:
6472
+ name: { type: string, description: "Category resource name" }
6473
+ displayName: { type: string, description: "Human-readable category name" }
6474
+ additionalCategories:
6475
+ type: array
6476
+ items:
6477
+ type: object
6478
+ properties:
6479
+ name: { type: string }
6480
+ displayName: { type: string }
6481
+ serviceItems:
6482
+ type: array
6483
+ description: "Services offered (returned when readMask includes 'serviceItems')"
6484
+ items:
6485
+ type: object
6486
+ properties:
6487
+ structuredServiceItem:
6488
+ type: object
6489
+ properties:
6490
+ serviceTypeId: { type: string }
6491
+ description: { type: string }
6492
+ freeFormServiceItem:
6493
+ type: object
6494
+ properties:
6495
+ category: { type: string }
6496
+ label:
6497
+ type: object
6498
+ properties:
6499
+ displayName: { type: string }
6500
+ languageCode: { type: string }
6501
+ price:
6502
+ type: object
6503
+ properties:
6504
+ currencyCode: { type: string }
6505
+ units: { type: string }
6506
+ nanos: { type: integer }
6431
6507
  example:
6432
6508
  success: true
6433
6509
  accountId: "64e1f0a9e2b5af0012ab34cd"
@@ -6450,6 +6526,13 @@ paths:
6450
6526
  profile:
6451
6527
  description: "Authentic New York style pizza since 1985"
6452
6528
  websiteUri: "https://joespizza.com"
6529
+ categories:
6530
+ primaryCategory:
6531
+ name: "categories/gcid:pizza_restaurant"
6532
+ displayName: "Pizza restaurant"
6533
+ additionalCategories:
6534
+ - name: "categories/gcid:italian_restaurant"
6535
+ displayName: "Italian restaurant"
6453
6536
  '400':
6454
6537
  description: Invalid request
6455
6538
  content:
@@ -6465,7 +6548,10 @@ paths:
6465
6548
  operationId: updateGoogleBusinessLocationDetails
6466
6549
  tags: [GMB Location Details]
6467
6550
  summary: Update location details
6468
- description: Updates GBP location details (hours, description, phone, website). The updateMask field is required and specifies which fields to update.
6551
+ description: |
6552
+ Updates GBP location details. The updateMask field is required and specifies which fields to update.
6553
+ This endpoint proxies Google's Business Information API locations.patch, so any valid updateMask field is supported.
6554
+ Common fields: regularHours, specialHours, profile.description, websiteUri, phoneNumbers, categories, serviceItems.
6469
6555
  parameters:
6470
6556
  - name: accountId
6471
6557
  in: path
@@ -6488,7 +6574,7 @@ paths:
6488
6574
  properties:
6489
6575
  updateMask:
6490
6576
  type: string
6491
- description: "Required. Comma-separated fields to update (e.g. 'regularHours', 'specialHours', 'profile.description')"
6577
+ description: "Required. Comma-separated fields to update (e.g. 'regularHours', 'specialHours', 'profile.description', 'categories', 'serviceItems'). Any valid Google Business Information API updateMask field is supported."
6492
6578
  regularHours:
6493
6579
  type: object
6494
6580
  properties:
@@ -6524,25 +6610,111 @@ paths:
6524
6610
  properties:
6525
6611
  primaryPhone: { type: string }
6526
6612
  additionalPhones: { type: array, items: { type: string } }
6527
- example:
6528
- updateMask: "regularHours,specialHours"
6529
- regularHours:
6530
- periods:
6531
- - openDay: "MONDAY"
6532
- openTime: "09:00"
6533
- closeDay: "MONDAY"
6534
- closeTime: "17:00"
6535
- - openDay: "SATURDAY"
6536
- openTime: "10:00"
6537
- closeDay: "SATURDAY"
6538
- closeTime: "14:00"
6539
- specialHours:
6540
- specialHourPeriods:
6541
- - startDate: { year: 2026, month: 12, day: 25 }
6542
- closed: true
6543
- - startDate: { year: 2026, month: 12, day: 31 }
6544
- openTime: "09:00"
6545
- closeTime: "15:00"
6613
+ categories:
6614
+ type: object
6615
+ description: "Primary and additional business categories. Use updateMask='categories' to update."
6616
+ properties:
6617
+ primaryCategory:
6618
+ type: object
6619
+ properties:
6620
+ name:
6621
+ type: string
6622
+ description: "Category resource name (e.g. 'categories/gcid:laundromat'). Use Google's Categories API to look up valid IDs."
6623
+ additionalCategories:
6624
+ type: array
6625
+ items:
6626
+ type: object
6627
+ properties:
6628
+ name:
6629
+ type: string
6630
+ description: "Category resource name (e.g. 'categories/gcid:dry_cleaner')"
6631
+ serviceItems:
6632
+ type: array
6633
+ description: "Services offered by the business. Use updateMask='serviceItems' to update."
6634
+ items:
6635
+ type: object
6636
+ properties:
6637
+ structuredServiceItem:
6638
+ type: object
6639
+ description: "A predefined service from Google's service type catalog"
6640
+ properties:
6641
+ serviceTypeId:
6642
+ type: string
6643
+ description: "Service type ID from Google's catalog (e.g. 'job_type_id:plumbing_drain_repair')"
6644
+ description:
6645
+ type: string
6646
+ description: "Optional description of the service"
6647
+ freeFormServiceItem:
6648
+ type: object
6649
+ description: "A custom service not in Google's catalog"
6650
+ properties:
6651
+ category:
6652
+ type: string
6653
+ description: "Category resource name this service belongs to (e.g. 'categories/gcid:laundromat')"
6654
+ label:
6655
+ type: object
6656
+ properties:
6657
+ displayName:
6658
+ type: string
6659
+ description: "Service name as displayed to users"
6660
+ languageCode:
6661
+ type: string
6662
+ description: "Language code (e.g. 'en')"
6663
+ price:
6664
+ type: object
6665
+ description: "Optional price for the service"
6666
+ properties:
6667
+ currencyCode: { type: string, description: "ISO 4217 currency code (e.g. 'USD')" }
6668
+ units: { type: string, description: "Whole units of the amount" }
6669
+ nanos: { type: integer, description: "Nano units (10^-9) of the amount" }
6670
+ examples:
6671
+ updateHours:
6672
+ summary: Update business hours
6673
+ value:
6674
+ updateMask: "regularHours,specialHours"
6675
+ regularHours:
6676
+ periods:
6677
+ - openDay: "MONDAY"
6678
+ openTime: "09:00"
6679
+ closeDay: "MONDAY"
6680
+ closeTime: "17:00"
6681
+ - openDay: "SATURDAY"
6682
+ openTime: "10:00"
6683
+ closeDay: "SATURDAY"
6684
+ closeTime: "14:00"
6685
+ specialHours:
6686
+ specialHourPeriods:
6687
+ - startDate: { year: 2026, month: 12, day: 25 }
6688
+ closed: true
6689
+ - startDate: { year: 2026, month: 12, day: 31 }
6690
+ openTime: "09:00"
6691
+ closeTime: "15:00"
6692
+ updateCategories:
6693
+ summary: Update business categories
6694
+ value:
6695
+ updateMask: "categories"
6696
+ categories:
6697
+ primaryCategory:
6698
+ name: "categories/gcid:laundromat"
6699
+ additionalCategories:
6700
+ - name: "categories/gcid:dry_cleaner"
6701
+ - name: "categories/gcid:laundry_service"
6702
+ updateServices:
6703
+ summary: Update service items
6704
+ value:
6705
+ updateMask: "serviceItems"
6706
+ serviceItems:
6707
+ - structuredServiceItem:
6708
+ serviceTypeId: "job_type_id:plumbing_drain_repair"
6709
+ description: "Full drain cleaning and repair service"
6710
+ - freeFormServiceItem:
6711
+ category: "categories/gcid:laundromat"
6712
+ label:
6713
+ displayName: "Wash & Fold Service"
6714
+ languageCode: "en"
6715
+ price:
6716
+ currencyCode: "USD"
6717
+ units: "25"
6546
6718
  responses:
6547
6719
  '200':
6548
6720
  description: Location updated successfully
@@ -10983,8 +11155,9 @@ paths:
10983
11155
  operationId: hideInboxComment
10984
11156
  summary: Hide comment
10985
11157
  description: |
10986
- Hide a comment on a post. Supported by Facebook, Instagram, and Threads.
11158
+ Hide a comment on a post. Supported by Facebook, Instagram, Threads, and X/Twitter.
10987
11159
  Hidden comments are only visible to the commenter and page admin.
11160
+ For X/Twitter, the reply must belong to a conversation started by the authenticated user. Requires the tweet.moderate.write scope and X API Basic tier or higher.
10988
11161
  tags: [Comments]
10989
11162
  security: [{ bearerAuth: [] }]
10990
11163
  parameters:
@@ -11026,7 +11199,7 @@ paths:
11026
11199
  operationId: unhideInboxComment
11027
11200
  summary: Unhide comment
11028
11201
  description: |
11029
- Unhide a previously hidden comment. Supported by Facebook, Instagram, and Threads.
11202
+ Unhide a previously hidden comment. Supported by Facebook, Instagram, Threads, and X/Twitter.
11030
11203
  tags: [Comments]
11031
11204
  security: [{ bearerAuth: [] }]
11032
11205
  parameters:
@@ -11241,6 +11414,210 @@ paths:
11241
11414
  '404':
11242
11415
  description: Account not found
11243
11416
 
11417
+ /v1/twitter/retweet:
11418
+ post:
11419
+ operationId: retweetPost
11420
+ summary: Retweet a post
11421
+ description: |
11422
+ Retweet (repost) a tweet by ID. Requires X API Basic tier ($200/mo) or higher.
11423
+ Rate limit: 50 requests per 15-min window. Shares the 300/3hr creation limit with tweet creation.
11424
+ tags: [Twitter Engagement]
11425
+ security: [{ bearerAuth: [] }]
11426
+ requestBody:
11427
+ required: true
11428
+ content:
11429
+ application/json:
11430
+ schema:
11431
+ type: object
11432
+ required: [accountId, tweetId]
11433
+ properties:
11434
+ accountId: { type: string, description: The social account ID }
11435
+ tweetId: { type: string, description: The ID of the tweet to retweet }
11436
+ responses:
11437
+ '200':
11438
+ description: Tweet retweeted
11439
+ content:
11440
+ application/json:
11441
+ schema:
11442
+ type: object
11443
+ properties:
11444
+ status: { type: string, example: success }
11445
+ tweetId: { type: string }
11446
+ retweeted: { type: boolean }
11447
+ platform: { type: string, example: twitter }
11448
+ '400': { description: Bad request or platform limitation }
11449
+ '401': { $ref: '#/components/responses/Unauthorized' }
11450
+ '404': { description: Account not found }
11451
+ delete:
11452
+ operationId: undoRetweet
11453
+ summary: Undo retweet
11454
+ description: |
11455
+ Undo a retweet (un-repost a tweet).
11456
+ tags: [Twitter Engagement]
11457
+ security: [{ bearerAuth: [] }]
11458
+ parameters:
11459
+ - name: accountId
11460
+ in: query
11461
+ required: true
11462
+ schema: { type: string }
11463
+ - name: tweetId
11464
+ in: query
11465
+ required: true
11466
+ schema: { type: string }
11467
+ description: The ID of the original tweet to un-retweet
11468
+ responses:
11469
+ '200':
11470
+ description: Retweet undone
11471
+ content:
11472
+ application/json:
11473
+ schema:
11474
+ type: object
11475
+ properties:
11476
+ status: { type: string, example: success }
11477
+ tweetId: { type: string }
11478
+ retweeted: { type: boolean, example: false }
11479
+ platform: { type: string, example: twitter }
11480
+ '400': { description: Bad request }
11481
+ '401': { $ref: '#/components/responses/Unauthorized' }
11482
+ '404': { description: Account not found }
11483
+
11484
+ /v1/twitter/bookmark:
11485
+ post:
11486
+ operationId: bookmarkPost
11487
+ summary: Bookmark a tweet
11488
+ description: |
11489
+ Bookmark a tweet by ID. Requires X API Basic tier ($200/mo) or higher.
11490
+ Requires the bookmark.write OAuth scope.
11491
+ Rate limit: 50 requests per 15-min window.
11492
+ tags: [Twitter Engagement]
11493
+ security: [{ bearerAuth: [] }]
11494
+ requestBody:
11495
+ required: true
11496
+ content:
11497
+ application/json:
11498
+ schema:
11499
+ type: object
11500
+ required: [accountId, tweetId]
11501
+ properties:
11502
+ accountId: { type: string, description: The social account ID }
11503
+ tweetId: { type: string, description: The ID of the tweet to bookmark }
11504
+ responses:
11505
+ '200':
11506
+ description: Tweet bookmarked
11507
+ content:
11508
+ application/json:
11509
+ schema:
11510
+ type: object
11511
+ properties:
11512
+ status: { type: string, example: success }
11513
+ tweetId: { type: string }
11514
+ bookmarked: { type: boolean }
11515
+ platform: { type: string, example: twitter }
11516
+ '400': { description: Bad request or platform limitation }
11517
+ '401': { $ref: '#/components/responses/Unauthorized' }
11518
+ '404': { description: Account not found }
11519
+ delete:
11520
+ operationId: removeBookmark
11521
+ summary: Remove bookmark
11522
+ description: |
11523
+ Remove a bookmark from a tweet.
11524
+ tags: [Twitter Engagement]
11525
+ security: [{ bearerAuth: [] }]
11526
+ parameters:
11527
+ - name: accountId
11528
+ in: query
11529
+ required: true
11530
+ schema: { type: string }
11531
+ - name: tweetId
11532
+ in: query
11533
+ required: true
11534
+ schema: { type: string }
11535
+ description: The ID of the tweet to unbookmark
11536
+ responses:
11537
+ '200':
11538
+ description: Bookmark removed
11539
+ content:
11540
+ application/json:
11541
+ schema:
11542
+ type: object
11543
+ properties:
11544
+ status: { type: string, example: success }
11545
+ tweetId: { type: string }
11546
+ bookmarked: { type: boolean, example: false }
11547
+ platform: { type: string, example: twitter }
11548
+ '400': { description: Bad request }
11549
+ '401': { $ref: '#/components/responses/Unauthorized' }
11550
+ '404': { description: Account not found }
11551
+
11552
+ /v1/twitter/follow:
11553
+ post:
11554
+ operationId: followUser
11555
+ summary: Follow a user
11556
+ description: |
11557
+ Follow a user on X/Twitter. Requires X API Basic tier ($200/mo) or higher.
11558
+ Requires the follows.write OAuth scope.
11559
+ For protected accounts, a follow request is sent instead (pending_follow will be true).
11560
+ tags: [Twitter Engagement]
11561
+ security: [{ bearerAuth: [] }]
11562
+ requestBody:
11563
+ required: true
11564
+ content:
11565
+ application/json:
11566
+ schema:
11567
+ type: object
11568
+ required: [accountId, targetUserId]
11569
+ properties:
11570
+ accountId: { type: string, description: The social account ID }
11571
+ targetUserId: { type: string, description: The Twitter ID of the user to follow }
11572
+ responses:
11573
+ '200':
11574
+ description: User followed or follow request sent
11575
+ content:
11576
+ application/json:
11577
+ schema:
11578
+ type: object
11579
+ properties:
11580
+ status: { type: string, example: success }
11581
+ targetUserId: { type: string }
11582
+ following: { type: boolean }
11583
+ pending_follow: { type: boolean, description: True if the target account is protected and a follow request was sent }
11584
+ platform: { type: string, example: twitter }
11585
+ '400': { description: Bad request or platform limitation }
11586
+ '401': { $ref: '#/components/responses/Unauthorized' }
11587
+ '404': { description: Account not found }
11588
+ delete:
11589
+ operationId: unfollowUser
11590
+ summary: Unfollow a user
11591
+ description: |
11592
+ Unfollow a user on X/Twitter.
11593
+ tags: [Twitter Engagement]
11594
+ security: [{ bearerAuth: [] }]
11595
+ parameters:
11596
+ - name: accountId
11597
+ in: query
11598
+ required: true
11599
+ schema: { type: string }
11600
+ - name: targetUserId
11601
+ in: query
11602
+ required: true
11603
+ schema: { type: string }
11604
+ description: The Twitter ID of the user to unfollow
11605
+ responses:
11606
+ '200':
11607
+ description: User unfollowed
11608
+ content:
11609
+ application/json:
11610
+ schema:
11611
+ type: object
11612
+ properties:
11613
+ status: { type: string, example: success }
11614
+ targetUserId: { type: string }
11615
+ following: { type: boolean, example: false }
11616
+ platform: { type: string, example: twitter }
11617
+ '400': { description: Bad request }
11618
+ '401': { $ref: '#/components/responses/Unauthorized' }
11619
+ '404': { description: Account not found }
11620
+
11244
11621
  /v1/inbox/reviews:
11245
11622
  get:
11246
11623
  operationId: listInboxReviews
@@ -65,7 +65,7 @@ describe 'CommentsApi' do
65
65
 
66
66
  # unit tests for hide_inbox_comment
67
67
  # Hide comment
68
- # Hide a comment on a post. Supported by Facebook, Instagram, and Threads. Hidden comments are only visible to the commenter and page admin.
68
+ # Hide a comment on a post. Supported by Facebook, Instagram, Threads, and X/Twitter. Hidden comments are only visible to the commenter and page admin. For X/Twitter, the reply must belong to a conversation started by the authenticated user. Requires the tweet.moderate.write scope and X API Basic tier or higher.
69
69
  # @param post_id
70
70
  # @param comment_id
71
71
  # @param hide_inbox_comment_request
@@ -140,7 +140,7 @@ describe 'CommentsApi' do
140
140
 
141
141
  # unit tests for unhide_inbox_comment
142
142
  # Unhide comment
143
- # Unhide a previously hidden comment. Supported by Facebook, Instagram, and Threads.
143
+ # Unhide a previously hidden comment. Supported by Facebook, Instagram, Threads, and X/Twitter.
144
144
  # @param post_id
145
145
  # @param comment_id
146
146
  # @param account_id