late-sdk 0.0.111 → 0.0.113

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -0
  3. data/docs/CreateInboxConversation201Response.md +20 -0
  4. data/docs/CreateInboxConversation201ResponseData.md +26 -0
  5. data/docs/CreateInboxConversation400Response.md +20 -0
  6. data/docs/CreateInboxConversation422Response.md +20 -0
  7. data/docs/CreateInboxConversationRequest.md +26 -0
  8. data/docs/CreatePostRequest.md +2 -0
  9. data/docs/EditPost200Response.md +24 -0
  10. data/docs/EditPostRequest.md +20 -0
  11. data/docs/FacebookPlatformData.md +3 -1
  12. data/docs/MessagesApi.md +70 -0
  13. data/docs/PostsApi.md +72 -0
  14. data/docs/TwitterPlatformData.md +3 -1
  15. data/docs/UpdatePostRequest.md +2 -0
  16. data/lib/late-sdk/api/messages_api.rb +68 -0
  17. data/lib/late-sdk/api/posts_api.rb +74 -0
  18. data/lib/late-sdk/models/create_inbox_conversation201_response.rb +156 -0
  19. data/lib/late-sdk/models/create_inbox_conversation201_response_data.rb +188 -0
  20. data/lib/late-sdk/models/create_inbox_conversation400_response.rb +190 -0
  21. data/lib/late-sdk/models/create_inbox_conversation422_response.rb +190 -0
  22. data/lib/late-sdk/models/create_inbox_conversation_request.rb +207 -0
  23. data/lib/late-sdk/models/create_post_request.rb +11 -1
  24. data/lib/late-sdk/models/edit_post200_response.rb +176 -0
  25. data/lib/late-sdk/models/edit_post_request.rb +216 -0
  26. data/lib/late-sdk/models/facebook_platform_data.rb +14 -2
  27. data/lib/late-sdk/models/twitter_platform_data.rb +16 -4
  28. data/lib/late-sdk/models/update_post_request.rb +11 -1
  29. data/lib/late-sdk/version.rb +1 -1
  30. data/lib/late-sdk.rb +7 -0
  31. data/openapi.yaml +207 -1
  32. data/spec/api/messages_api_spec.rb +12 -0
  33. data/spec/api/posts_api_spec.rb +13 -0
  34. data/spec/models/create_inbox_conversation201_response_data_spec.rb +60 -0
  35. data/spec/models/create_inbox_conversation201_response_spec.rb +42 -0
  36. data/spec/models/create_inbox_conversation400_response_spec.rb +46 -0
  37. data/spec/models/create_inbox_conversation422_response_spec.rb +46 -0
  38. data/spec/models/create_inbox_conversation_request_spec.rb +60 -0
  39. data/spec/models/create_post_request_spec.rb +6 -0
  40. data/spec/models/edit_post200_response_spec.rb +54 -0
  41. data/spec/models/edit_post_request_spec.rb +46 -0
  42. data/spec/models/facebook_platform_data_spec.rb +6 -0
  43. data/spec/models/twitter_platform_data_spec.rb +6 -0
  44. data/spec/models/update_post_request_spec.rb +6 -0
  45. data/zernio-sdk-0.0.113.gem +0 -0
  46. metadata +31 -3
  47. data/zernio-sdk-0.0.111.gem +0 -0
@@ -0,0 +1,216 @@
1
+ =begin
2
+ #Zernio API
3
+
4
+ #API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api
5
+
6
+ The version of the OpenAPI document: 1.0.1
7
+ Contact: support@zernio.com
8
+ Generated by: https://openapi-generator.tech
9
+ Generator version: 7.19.0
10
+
11
+ =end
12
+
13
+ require 'date'
14
+ require 'time'
15
+
16
+ module Late
17
+ class EditPostRequest < ApiModelBase
18
+ # The platform to edit the post on. Currently only twitter is supported.
19
+ attr_accessor :platform
20
+
21
+ # The new tweet text content
22
+ attr_accessor :content
23
+
24
+ class EnumAttributeValidator
25
+ attr_reader :datatype
26
+ attr_reader :allowable_values
27
+
28
+ def initialize(datatype, allowable_values)
29
+ @allowable_values = allowable_values.map do |value|
30
+ case datatype.to_s
31
+ when /Integer/i
32
+ value.to_i
33
+ when /Float/i
34
+ value.to_f
35
+ else
36
+ value
37
+ end
38
+ end
39
+ end
40
+
41
+ def valid?(value)
42
+ !value || allowable_values.include?(value)
43
+ end
44
+ end
45
+
46
+ # Attribute mapping from ruby-style variable name to JSON key.
47
+ def self.attribute_map
48
+ {
49
+ :'platform' => :'platform',
50
+ :'content' => :'content'
51
+ }
52
+ end
53
+
54
+ # Returns attribute mapping this model knows about
55
+ def self.acceptable_attribute_map
56
+ attribute_map
57
+ end
58
+
59
+ # Returns all the JSON keys this model knows about
60
+ def self.acceptable_attributes
61
+ acceptable_attribute_map.values
62
+ end
63
+
64
+ # Attribute type mapping.
65
+ def self.openapi_types
66
+ {
67
+ :'platform' => :'String',
68
+ :'content' => :'String'
69
+ }
70
+ end
71
+
72
+ # List of attributes with nullable: true
73
+ def self.openapi_nullable
74
+ Set.new([
75
+ ])
76
+ end
77
+
78
+ # Initializes the object
79
+ # @param [Hash] attributes Model attributes in the form of hash
80
+ def initialize(attributes = {})
81
+ if (!attributes.is_a?(Hash))
82
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Late::EditPostRequest` initialize method"
83
+ end
84
+
85
+ # check to see if the attribute exists and convert string to symbol for hash key
86
+ acceptable_attribute_map = self.class.acceptable_attribute_map
87
+ attributes = attributes.each_with_object({}) { |(k, v), h|
88
+ if (!acceptable_attribute_map.key?(k.to_sym))
89
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Late::EditPostRequest`. Please check the name to make sure it's valid. List of attributes: " + acceptable_attribute_map.keys.inspect
90
+ end
91
+ h[k.to_sym] = v
92
+ }
93
+
94
+ if attributes.key?(:'platform')
95
+ self.platform = attributes[:'platform']
96
+ else
97
+ self.platform = nil
98
+ end
99
+
100
+ if attributes.key?(:'content')
101
+ self.content = attributes[:'content']
102
+ else
103
+ self.content = nil
104
+ end
105
+ end
106
+
107
+ # Show invalid properties with the reasons. Usually used together with valid?
108
+ # @return Array for valid properties with the reasons
109
+ def list_invalid_properties
110
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
111
+ invalid_properties = Array.new
112
+ if @platform.nil?
113
+ invalid_properties.push('invalid value for "platform", platform cannot be nil.')
114
+ end
115
+
116
+ if @content.nil?
117
+ invalid_properties.push('invalid value for "content", content cannot be nil.')
118
+ end
119
+
120
+ invalid_properties
121
+ end
122
+
123
+ # Check to see if the all the properties in the model are valid
124
+ # @return true if the model is valid
125
+ def valid?
126
+ warn '[DEPRECATED] the `valid?` method is obsolete'
127
+ return false if @platform.nil?
128
+ platform_validator = EnumAttributeValidator.new('String', ["twitter"])
129
+ return false unless platform_validator.valid?(@platform)
130
+ return false if @content.nil?
131
+ true
132
+ end
133
+
134
+ # Custom attribute writer method checking allowed values (enum).
135
+ # @param [Object] platform Object to be assigned
136
+ def platform=(platform)
137
+ validator = EnumAttributeValidator.new('String', ["twitter"])
138
+ unless validator.valid?(platform)
139
+ fail ArgumentError, "invalid value for \"platform\", must be one of #{validator.allowable_values}."
140
+ end
141
+ @platform = platform
142
+ end
143
+
144
+ # Custom attribute writer method with validation
145
+ # @param [Object] content Value to be assigned
146
+ def content=(content)
147
+ if content.nil?
148
+ fail ArgumentError, 'content cannot be nil'
149
+ end
150
+
151
+ @content = content
152
+ end
153
+
154
+ # Checks equality by comparing each attribute.
155
+ # @param [Object] Object to be compared
156
+ def ==(o)
157
+ return true if self.equal?(o)
158
+ self.class == o.class &&
159
+ platform == o.platform &&
160
+ content == o.content
161
+ end
162
+
163
+ # @see the `==` method
164
+ # @param [Object] Object to be compared
165
+ def eql?(o)
166
+ self == o
167
+ end
168
+
169
+ # Calculates hash code according to all attributes.
170
+ # @return [Integer] Hash code
171
+ def hash
172
+ [platform, content].hash
173
+ end
174
+
175
+ # Builds the object from hash
176
+ # @param [Hash] attributes Model attributes in the form of hash
177
+ # @return [Object] Returns the model itself
178
+ def self.build_from_hash(attributes)
179
+ return nil unless attributes.is_a?(Hash)
180
+ attributes = attributes.transform_keys(&:to_sym)
181
+ transformed_hash = {}
182
+ openapi_types.each_pair do |key, type|
183
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
184
+ transformed_hash["#{key}"] = nil
185
+ elsif type =~ /\AArray<(.*)>/i
186
+ # check to ensure the input is an array given that the attribute
187
+ # is documented as an array but the input is not
188
+ if attributes[attribute_map[key]].is_a?(Array)
189
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
190
+ end
191
+ elsif !attributes[attribute_map[key]].nil?
192
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
193
+ end
194
+ end
195
+ new(transformed_hash)
196
+ end
197
+
198
+ # Returns the object in the form of hash
199
+ # @return [Hash] Returns the object in the form of hash
200
+ def to_hash
201
+ hash = {}
202
+ self.class.attribute_map.each_pair do |attr, param|
203
+ value = self.send(attr)
204
+ if value.nil?
205
+ is_nullable = self.class.openapi_nullable.include?(attr)
206
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
207
+ end
208
+
209
+ hash[param] = _to_hash(value)
210
+ end
211
+ hash
212
+ end
213
+
214
+ end
215
+
216
+ end
@@ -16,13 +16,16 @@ require 'time'
16
16
  module Late
17
17
  # Feed posts support up to 10 images (no mixed video+image). Stories require single media (24h, no captions). Reels require single vertical video (9:16, 3-60s).
18
18
  class FacebookPlatformData < ApiModelBase
19
+ # When true, creates the post as an unpublished draft visible in Facebook Publishing Tools instead of publishing immediately. Supported for feed posts (text, link, image, video) and reels. Not supported for stories. Drafts expire after ~30 days.
20
+ attr_accessor :draft
21
+
19
22
  # Set to 'story' for Page Stories (24h ephemeral) or 'reel' for Reels (short vertical video). Defaults to feed post if omitted.
20
23
  attr_accessor :content_type
21
24
 
22
25
  # Reel title (only for contentType=reel). Separate from the caption/content field.
23
26
  attr_accessor :title
24
27
 
25
- # Optional first comment to post immediately after publishing (feed posts only, not stories or reels)
28
+ # Optional first comment to post immediately after publishing (feed posts and reels, not stories). Skipped when draft is true.
26
29
  attr_accessor :first_comment
27
30
 
28
31
  # Target Facebook Page ID for multi-page posting. If omitted, uses the default page. Use GET /v1/accounts/{id}/facebook-page to list pages.
@@ -53,6 +56,7 @@ module Late
53
56
  # Attribute mapping from ruby-style variable name to JSON key.
54
57
  def self.attribute_map
55
58
  {
59
+ :'draft' => :'draft',
56
60
  :'content_type' => :'contentType',
57
61
  :'title' => :'title',
58
62
  :'first_comment' => :'firstComment',
@@ -73,6 +77,7 @@ module Late
73
77
  # Attribute type mapping.
74
78
  def self.openapi_types
75
79
  {
80
+ :'draft' => :'Boolean',
76
81
  :'content_type' => :'String',
77
82
  :'title' => :'String',
78
83
  :'first_comment' => :'String',
@@ -102,6 +107,12 @@ module Late
102
107
  h[k.to_sym] = v
103
108
  }
104
109
 
110
+ if attributes.key?(:'draft')
111
+ self.draft = attributes[:'draft']
112
+ else
113
+ self.draft = false
114
+ end
115
+
105
116
  if attributes.key?(:'content_type')
106
117
  self.content_type = attributes[:'content_type']
107
118
  end
@@ -151,6 +162,7 @@ module Late
151
162
  def ==(o)
152
163
  return true if self.equal?(o)
153
164
  self.class == o.class &&
165
+ draft == o.draft &&
154
166
  content_type == o.content_type &&
155
167
  title == o.title &&
156
168
  first_comment == o.first_comment &&
@@ -166,7 +178,7 @@ module Late
166
178
  # Calculates hash code according to all attributes.
167
179
  # @return [Integer] Hash code
168
180
  def hash
169
- [content_type, title, first_comment, page_id].hash
181
+ [draft, content_type, title, first_comment, page_id].hash
170
182
  end
171
183
 
172
184
  # Builds the object from hash
@@ -26,6 +26,9 @@ module Late
26
26
 
27
27
  attr_accessor :poll
28
28
 
29
+ # Enable long video uploads (over 140 seconds) using amplify_video media category. Requires the connected X account to have an active X Premium subscription. When true, videos are uploaded with the amplify_video category which supports longer durations (up to 10 minutes via API). When false or omitted, the standard tweet_video category is used (140 second limit). Note that not all Premium accounts have API long-video access, as X may require separate allowlisting.
30
+ attr_accessor :long_video
31
+
29
32
  class EnumAttributeValidator
30
33
  attr_reader :datatype
31
34
  attr_reader :allowable_values
@@ -54,7 +57,8 @@ module Late
54
57
  :'reply_to_tweet_id' => :'replyToTweetId',
55
58
  :'reply_settings' => :'replySettings',
56
59
  :'thread_items' => :'threadItems',
57
- :'poll' => :'poll'
60
+ :'poll' => :'poll',
61
+ :'long_video' => :'longVideo'
58
62
  }
59
63
  end
60
64
 
@@ -74,7 +78,8 @@ module Late
74
78
  :'reply_to_tweet_id' => :'String',
75
79
  :'reply_settings' => :'String',
76
80
  :'thread_items' => :'Array<TwitterPlatformDataThreadItemsInner>',
77
- :'poll' => :'TwitterPlatformDataPoll'
81
+ :'poll' => :'TwitterPlatformDataPoll',
82
+ :'long_video' => :'Boolean'
78
83
  }
79
84
  end
80
85
 
@@ -117,6 +122,12 @@ module Late
117
122
  if attributes.key?(:'poll')
118
123
  self.poll = attributes[:'poll']
119
124
  end
125
+
126
+ if attributes.key?(:'long_video')
127
+ self.long_video = attributes[:'long_video']
128
+ else
129
+ self.long_video = false
130
+ end
120
131
  end
121
132
 
122
133
  # Show invalid properties with the reasons. Usually used together with valid?
@@ -154,7 +165,8 @@ module Late
154
165
  reply_to_tweet_id == o.reply_to_tweet_id &&
155
166
  reply_settings == o.reply_settings &&
156
167
  thread_items == o.thread_items &&
157
- poll == o.poll
168
+ poll == o.poll &&
169
+ long_video == o.long_video
158
170
  end
159
171
 
160
172
  # @see the `==` method
@@ -166,7 +178,7 @@ module Late
166
178
  # Calculates hash code according to all attributes.
167
179
  # @return [Integer] Hash code
168
180
  def hash
169
- [reply_to_tweet_id, reply_settings, thread_items, poll].hash
181
+ [reply_to_tweet_id, reply_settings, thread_items, poll, long_video].hash
170
182
  end
171
183
 
172
184
  # Builds the object from hash
@@ -22,6 +22,9 @@ module Late
22
22
  # Root-level TikTok settings applied to all TikTok platforms. Merged into each platform's platformSpecificData, with platform-specific settings taking precedence.
23
23
  attr_accessor :tiktok_settings
24
24
 
25
+ # Root-level Facebook settings applied to all Facebook platforms. Merged into each platform's platformSpecificData, with platform-specific settings taking precedence.
26
+ attr_accessor :facebook_settings
27
+
25
28
  attr_accessor :recycling
26
29
 
27
30
  # Attribute mapping from ruby-style variable name to JSON key.
@@ -30,6 +33,7 @@ module Late
30
33
  :'content' => :'content',
31
34
  :'scheduled_for' => :'scheduledFor',
32
35
  :'tiktok_settings' => :'tiktokSettings',
36
+ :'facebook_settings' => :'facebookSettings',
33
37
  :'recycling' => :'recycling'
34
38
  }
35
39
  end
@@ -50,6 +54,7 @@ module Late
50
54
  :'content' => :'String',
51
55
  :'scheduled_for' => :'Time',
52
56
  :'tiktok_settings' => :'TikTokPlatformData',
57
+ :'facebook_settings' => :'FacebookPlatformData',
53
58
  :'recycling' => :'RecyclingConfig'
54
59
  }
55
60
  end
@@ -88,6 +93,10 @@ module Late
88
93
  self.tiktok_settings = attributes[:'tiktok_settings']
89
94
  end
90
95
 
96
+ if attributes.key?(:'facebook_settings')
97
+ self.facebook_settings = attributes[:'facebook_settings']
98
+ end
99
+
91
100
  if attributes.key?(:'recycling')
92
101
  self.recycling = attributes[:'recycling']
93
102
  end
@@ -116,6 +125,7 @@ module Late
116
125
  content == o.content &&
117
126
  scheduled_for == o.scheduled_for &&
118
127
  tiktok_settings == o.tiktok_settings &&
128
+ facebook_settings == o.facebook_settings &&
119
129
  recycling == o.recycling
120
130
  end
121
131
 
@@ -128,7 +138,7 @@ module Late
128
138
  # Calculates hash code according to all attributes.
129
139
  # @return [Integer] Hash code
130
140
  def hash
131
- [content, scheduled_for, tiktok_settings, recycling].hash
141
+ [content, scheduled_for, tiktok_settings, facebook_settings, recycling].hash
132
142
  end
133
143
 
134
144
  # Builds the object from hash
@@ -11,5 +11,5 @@ Generator version: 7.19.0
11
11
  =end
12
12
 
13
13
  module Late
14
- VERSION = '0.0.111'
14
+ VERSION = '0.0.113'
15
15
  end
data/lib/late-sdk.rb CHANGED
@@ -111,6 +111,11 @@ require 'late-sdk/models/create_google_business_media200_response'
111
111
  require 'late-sdk/models/create_google_business_media_request'
112
112
  require 'late-sdk/models/create_google_business_place_action200_response'
113
113
  require 'late-sdk/models/create_google_business_place_action_request'
114
+ require 'late-sdk/models/create_inbox_conversation201_response'
115
+ require 'late-sdk/models/create_inbox_conversation201_response_data'
116
+ require 'late-sdk/models/create_inbox_conversation400_response'
117
+ require 'late-sdk/models/create_inbox_conversation422_response'
118
+ require 'late-sdk/models/create_inbox_conversation_request'
114
119
  require 'late-sdk/models/create_invite_token201_response'
115
120
  require 'late-sdk/models/create_invite_token_request'
116
121
  require 'late-sdk/models/create_post409_response'
@@ -163,6 +168,8 @@ require 'late-sdk/models/edit_inbox_message200_response_data'
163
168
  require 'late-sdk/models/edit_inbox_message_request'
164
169
  require 'late-sdk/models/edit_inbox_message_request_reply_markup'
165
170
  require 'late-sdk/models/edit_inbox_message_request_reply_markup_keyboard_inner_inner'
171
+ require 'late-sdk/models/edit_post200_response'
172
+ require 'late-sdk/models/edit_post_request'
166
173
  require 'late-sdk/models/enroll_contacts200_response'
167
174
  require 'late-sdk/models/enroll_contacts_request'
168
175
  require 'late-sdk/models/error_response'
data/openapi.yaml CHANGED
@@ -1633,6 +1633,10 @@ components:
1633
1633
  required:
1634
1634
  - options
1635
1635
  - duration_minutes
1636
+ longVideo:
1637
+ type: boolean
1638
+ default: false
1639
+ description: Enable long video uploads (over 140 seconds) using amplify_video media category. Requires the connected X account to have an active X Premium subscription. When true, videos are uploaded with the amplify_video category which supports longer durations (up to 10 minutes via API). When false or omitted, the standard tweet_video category is used (140 second limit). Note that not all Premium accounts have API long-video access, as X may require separate allowlisting.
1636
1640
 
1637
1641
  ThreadsPlatformData:
1638
1642
  type: object
@@ -1657,6 +1661,10 @@ components:
1657
1661
  FacebookPlatformData:
1658
1662
  type: object
1659
1663
  properties:
1664
+ draft:
1665
+ type: boolean
1666
+ description: When true, creates the post as an unpublished draft visible in Facebook Publishing Tools instead of publishing immediately. Supported for feed posts (text, link, image, video) and reels. Not supported for stories. Drafts expire after ~30 days.
1667
+ default: false
1660
1668
  contentType:
1661
1669
  type: string
1662
1670
  enum: [story, reel]
@@ -1666,7 +1674,7 @@ components:
1666
1674
  description: Reel title (only for contentType=reel). Separate from the caption/content field.
1667
1675
  firstComment:
1668
1676
  type: string
1669
- description: Optional first comment to post immediately after publishing (feed posts only, not stories or reels)
1677
+ description: Optional first comment to post immediately after publishing (feed posts and reels, not stories). Skipped when draft is true.
1670
1678
  pageId:
1671
1679
  type: string
1672
1680
  description: Target Facebook Page ID for multi-page posting. If omitted, uses the default page. Use GET /v1/accounts/{id}/facebook-page to list pages.
@@ -5164,6 +5172,9 @@ paths:
5164
5172
  tiktokSettings:
5165
5173
  $ref: '#/components/schemas/TikTokPlatformData'
5166
5174
  description: Root-level TikTok settings applied to all TikTok platforms. Merged into each platform's platformSpecificData, with platform-specific settings taking precedence.
5175
+ facebookSettings:
5176
+ $ref: '#/components/schemas/FacebookPlatformData'
5177
+ description: Root-level Facebook settings applied to all Facebook platforms. Merged into each platform's platformSpecificData, with platform-specific settings taking precedence.
5167
5178
  recycling:
5168
5179
  $ref: '#/components/schemas/RecyclingConfig'
5169
5180
  queuedFromProfile:
@@ -5176,6 +5187,16 @@ paths:
5176
5187
  Only used when queuedFromProfile is also provided.
5177
5188
  If omitted, uses the profile's default queue.
5178
5189
  examples:
5190
+ facebookDraft:
5191
+ summary: Facebook draft post (visible in Publishing Tools)
5192
+ value:
5193
+ content: "Draft post for review before publishing"
5194
+ platforms:
5195
+ - platform: facebook
5196
+ accountId: "64e1f0a9e2b5af0012ab34cd"
5197
+ publishNow: true
5198
+ facebookSettings:
5199
+ draft: true
5179
5200
  recyclingPost:
5180
5201
  summary: Post with weekly recycling and content variations
5181
5202
  value:
@@ -5521,6 +5542,9 @@ paths:
5521
5542
  tiktokSettings:
5522
5543
  $ref: '#/components/schemas/TikTokPlatformData'
5523
5544
  description: Root-level TikTok settings applied to all TikTok platforms. Merged into each platform's platformSpecificData, with platform-specific settings taking precedence.
5545
+ facebookSettings:
5546
+ $ref: '#/components/schemas/FacebookPlatformData'
5547
+ description: Root-level Facebook settings applied to all Facebook platforms. Merged into each platform's platformSpecificData, with platform-specific settings taking precedence.
5524
5548
  recycling:
5525
5549
  $ref: '#/components/schemas/RecyclingConfig'
5526
5550
  additionalProperties: true
@@ -5762,6 +5786,69 @@ paths:
5762
5786
  '404': { $ref: '#/components/responses/NotFound' }
5763
5787
  '500':
5764
5788
  description: Platform API deletion failed
5789
+ /v1/posts/{postId}/edit:
5790
+ post:
5791
+ operationId: editPost
5792
+ tags: [Posts]
5793
+ summary: Edit published post
5794
+ description: |
5795
+ Edit a published post on a social media platform. Currently only supported for X (Twitter).
5796
+
5797
+ **Requirements:**
5798
+ - Connected X account must have an active X Premium subscription
5799
+ - Must be within 1 hour of original publish time
5800
+ - Maximum 5 edits per tweet (enforced by X)
5801
+ - Text-only edits (media changes are not supported)
5802
+
5803
+ The post record in Zernio is updated with the new content and edit history.
5804
+ parameters:
5805
+ - name: postId
5806
+ in: path
5807
+ required: true
5808
+ schema: { type: string }
5809
+ requestBody:
5810
+ required: true
5811
+ content:
5812
+ application/json:
5813
+ schema:
5814
+ type: object
5815
+ required: [platform, content]
5816
+ properties:
5817
+ platform:
5818
+ type: string
5819
+ description: The platform to edit the post on. Currently only twitter is supported.
5820
+ enum: [twitter]
5821
+ content:
5822
+ type: string
5823
+ description: The new tweet text content
5824
+ example:
5825
+ platform: "twitter"
5826
+ content: "Updated tweet text with corrected information"
5827
+ responses:
5828
+ '200':
5829
+ description: Post edited successfully
5830
+ content:
5831
+ application/json:
5832
+ schema:
5833
+ type: object
5834
+ properties:
5835
+ success: { type: boolean }
5836
+ id: { type: string, description: New tweet ID assigned by X after edit }
5837
+ url: { type: string, format: uri, description: URL of the edited tweet }
5838
+ message: { type: string }
5839
+ example:
5840
+ success: true
5841
+ id: "1234567890123456790"
5842
+ url: "https://twitter.com/i/web/status/1234567890123456790"
5843
+ message: "Tweet edited successfully"
5844
+ '400':
5845
+ description: "Invalid request: platform not supported, post not published, edit window expired, not Premium, or missing content."
5846
+ '401': { $ref: '#/components/responses/Unauthorized' }
5847
+ '403':
5848
+ description: Forbidden
5849
+ '404': { $ref: '#/components/responses/NotFound' }
5850
+ '500':
5851
+ description: Platform API edit failed
5765
5852
  /v1/posts/{postId}/update-metadata:
5766
5853
  post:
5767
5854
  operationId: updatePostMetadata
@@ -11492,6 +11579,125 @@ paths:
11492
11579
  '401': { $ref: '#/components/responses/Unauthorized' }
11493
11580
  '403':
11494
11581
  description: Inbox addon required
11582
+ post:
11583
+ operationId: createInboxConversation
11584
+ summary: Create conversation
11585
+ description: |
11586
+ Initiate a new direct message conversation with a specified user. If a conversation already exists with the recipient, the message is added to the existing thread.
11587
+
11588
+ **Currently supported platforms:** Twitter/X only. Other platforms will return `PLATFORM_NOT_SUPPORTED`.
11589
+
11590
+ **DM eligibility:** Before sending, the endpoint checks if the recipient accepts DMs from your account (via the `receives_your_dm` field). If not, a 422 error with code `DM_NOT_ALLOWED` is returned. You can skip this check with `skipDmCheck: true` if you have already verified eligibility.
11591
+
11592
+ **X API tier requirement:** DM write endpoints require X API Pro tier ($5,000/month) or Enterprise access. This applies to BYOK (Bring Your Own Key) users who provide their own X API credentials.
11593
+
11594
+ **Rate limits:** 200 requests per 15 minutes, 1,000 per 24 hours per user, 15,000 per 24 hours per app (shared across all DM endpoints).
11595
+ tags: [Messages]
11596
+ security: [{ bearerAuth: [] }]
11597
+ requestBody:
11598
+ required: true
11599
+ content:
11600
+ application/json:
11601
+ schema:
11602
+ type: object
11603
+ required: [accountId]
11604
+ properties:
11605
+ accountId:
11606
+ type: string
11607
+ description: The social account ID to send from
11608
+ participantId:
11609
+ type: string
11610
+ description: Twitter numeric user ID of the recipient. Provide either this or `participantUsername`.
11611
+ participantUsername:
11612
+ type: string
11613
+ description: Twitter username (with or without @) of the recipient. Resolved to a user ID via lookup. Provide either this or `participantId`.
11614
+ message:
11615
+ type: string
11616
+ description: Text content of the message. At least one of `message` or attachment is required.
11617
+ skipDmCheck:
11618
+ type: boolean
11619
+ default: false
11620
+ description: Skip the `receives_your_dm` eligibility check before sending. Use if you have already verified the recipient accepts DMs.
11621
+ multipart/form-data:
11622
+ schema:
11623
+ type: object
11624
+ required: [accountId]
11625
+ properties:
11626
+ accountId:
11627
+ type: string
11628
+ description: The social account ID to send from
11629
+ participantId:
11630
+ type: string
11631
+ description: Twitter numeric user ID of the recipient
11632
+ participantUsername:
11633
+ type: string
11634
+ description: Twitter username (with or without @) of the recipient
11635
+ message:
11636
+ type: string
11637
+ description: Text content of the message
11638
+ attachment:
11639
+ type: string
11640
+ format: binary
11641
+ description: Media attachment (image or video). One attachment per message.
11642
+ skipDmCheck:
11643
+ type: string
11644
+ enum: ['true', 'false']
11645
+ default: 'false'
11646
+ description: Skip the DM eligibility check
11647
+ responses:
11648
+ '201':
11649
+ description: Conversation created successfully
11650
+ content:
11651
+ application/json:
11652
+ schema:
11653
+ type: object
11654
+ properties:
11655
+ success: { type: boolean, example: true }
11656
+ data:
11657
+ type: object
11658
+ properties:
11659
+ messageId:
11660
+ type: string
11661
+ description: Platform message ID (dm_event_id)
11662
+ conversationId:
11663
+ type: string
11664
+ description: Platform conversation ID (dm_conversation_id)
11665
+ participantId:
11666
+ type: string
11667
+ description: Twitter numeric user ID of the recipient
11668
+ participantName:
11669
+ type: string
11670
+ nullable: true
11671
+ description: Display name of the recipient
11672
+ participantUsername:
11673
+ type: string
11674
+ nullable: true
11675
+ description: Twitter username of the recipient
11676
+ '400':
11677
+ description: Validation error or platform not supported
11678
+ content:
11679
+ application/json:
11680
+ schema:
11681
+ type: object
11682
+ properties:
11683
+ error: { type: string }
11684
+ code: { type: string, enum: [PLATFORM_NOT_SUPPORTED] }
11685
+ '401': { $ref: '#/components/responses/Unauthorized' }
11686
+ '403':
11687
+ description: Inbox addon required or profile limit reached
11688
+ '404':
11689
+ description: Account or recipient user not found
11690
+ '422':
11691
+ description: Recipient does not accept DMs from this account
11692
+ content:
11693
+ application/json:
11694
+ schema:
11695
+ type: object
11696
+ properties:
11697
+ error: { type: string }
11698
+ code: { type: string, enum: [DM_NOT_ALLOWED] }
11699
+ '429':
11700
+ description: X API rate limit exceeded
11495
11701
  /v1/inbox/conversations/{conversationId}:
11496
11702
  get:
11497
11703
  operationId: getInboxConversation