ark-email 0.6.0 → 0.8.0

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/CHANGELOG.md +29 -0
  3. data/README.md +22 -6
  4. data/lib/ark_email/models/email_send_batch_params.rb +35 -2
  5. data/lib/ark_email/models/email_send_params.rb +26 -1
  6. data/lib/ark_email/models/webhook_list_deliveries_params.rb +79 -0
  7. data/lib/ark_email/models/webhook_list_deliveries_response.rb +154 -0
  8. data/lib/ark_email/models/webhook_replay_delivery_params.rb +20 -0
  9. data/lib/ark_email/models/webhook_replay_delivery_response.rb +82 -0
  10. data/lib/ark_email/models/webhook_retrieve_delivery_params.rb +20 -0
  11. data/lib/ark_email/models/webhook_retrieve_delivery_response.rb +198 -0
  12. data/lib/ark_email/models.rb +6 -0
  13. data/lib/ark_email/resources/emails.rb +4 -2
  14. data/lib/ark_email/resources/webhooks.rb +127 -0
  15. data/lib/ark_email/version.rb +1 -1
  16. data/lib/ark_email.rb +6 -0
  17. data/rbi/ark_email/models/email_send_batch_params.rbi +51 -1
  18. data/rbi/ark_email/models/email_send_params.rbi +42 -0
  19. data/rbi/ark_email/models/webhook_list_deliveries_params.rbi +172 -0
  20. data/rbi/ark_email/models/webhook_list_deliveries_response.rbi +257 -0
  21. data/rbi/ark_email/models/webhook_replay_delivery_params.rbi +38 -0
  22. data/rbi/ark_email/models/webhook_replay_delivery_response.rbi +132 -0
  23. data/rbi/ark_email/models/webhook_retrieve_delivery_params.rbi +38 -0
  24. data/rbi/ark_email/models/webhook_retrieve_delivery_response.rbi +371 -0
  25. data/rbi/ark_email/models.rbi +7 -0
  26. data/rbi/ark_email/resources/emails.rbi +21 -1
  27. data/rbi/ark_email/resources/webhooks.rbi +105 -0
  28. data/sig/ark_email/models/email_send_batch_params.rbs +5 -0
  29. data/sig/ark_email/models/email_send_params.rbs +5 -0
  30. data/sig/ark_email/models/webhook_list_deliveries_params.rbs +90 -0
  31. data/sig/ark_email/models/webhook_list_deliveries_response.rbs +127 -0
  32. data/sig/ark_email/models/webhook_replay_delivery_params.rbs +23 -0
  33. data/sig/ark_email/models/webhook_replay_delivery_response.rbs +72 -0
  34. data/sig/ark_email/models/webhook_retrieve_delivery_params.rbs +23 -0
  35. data/sig/ark_email/models/webhook_retrieve_delivery_response.rbs +158 -0
  36. data/sig/ark_email/models.rbs +6 -0
  37. data/sig/ark_email/resources/emails.rbs +1 -0
  38. data/sig/ark_email/resources/webhooks.rbs +23 -0
  39. metadata +20 -2
@@ -0,0 +1,198 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ArkEmail
4
+ module Models
5
+ # @see ArkEmail::Resources::Webhooks#retrieve_delivery
6
+ class WebhookRetrieveDeliveryResponse < ArkEmail::Internal::Type::BaseModel
7
+ # @!attribute data
8
+ # Full details of a webhook delivery including request and response
9
+ #
10
+ # @return [ArkEmail::Models::WebhookRetrieveDeliveryResponse::Data]
11
+ required :data, -> { ArkEmail::Models::WebhookRetrieveDeliveryResponse::Data }
12
+
13
+ # @!attribute meta
14
+ #
15
+ # @return [ArkEmail::Models::APIMeta]
16
+ required :meta, -> { ArkEmail::APIMeta }
17
+
18
+ # @!attribute success
19
+ #
20
+ # @return [Boolean, true]
21
+ required :success, const: true
22
+
23
+ # @!method initialize(data:, meta:, success: true)
24
+ # Detailed information about a webhook delivery attempt
25
+ #
26
+ # @param data [ArkEmail::Models::WebhookRetrieveDeliveryResponse::Data] Full details of a webhook delivery including request and response
27
+ #
28
+ # @param meta [ArkEmail::Models::APIMeta]
29
+ #
30
+ # @param success [Boolean, true]
31
+
32
+ # @see ArkEmail::Models::WebhookRetrieveDeliveryResponse#data
33
+ class Data < ArkEmail::Internal::Type::BaseModel
34
+ # @!attribute id
35
+ # Unique delivery ID (UUID)
36
+ #
37
+ # @return [String]
38
+ required :id, String
39
+
40
+ # @!attribute attempt
41
+ # Attempt number for this delivery
42
+ #
43
+ # @return [Integer]
44
+ required :attempt, Integer
45
+
46
+ # @!attribute event
47
+ # Event type that triggered this delivery
48
+ #
49
+ # @return [Symbol, ArkEmail::Models::WebhookRetrieveDeliveryResponse::Data::Event]
50
+ required :event, enum: -> { ArkEmail::Models::WebhookRetrieveDeliveryResponse::Data::Event }
51
+
52
+ # @!attribute request
53
+ # The request that was sent to your endpoint
54
+ #
55
+ # @return [ArkEmail::Models::WebhookRetrieveDeliveryResponse::Data::Request]
56
+ required :request, -> { ArkEmail::Models::WebhookRetrieveDeliveryResponse::Data::Request }
57
+
58
+ # @!attribute response
59
+ # The response received from your endpoint
60
+ #
61
+ # @return [ArkEmail::Models::WebhookRetrieveDeliveryResponse::Data::Response]
62
+ required :response, -> { ArkEmail::Models::WebhookRetrieveDeliveryResponse::Data::Response }
63
+
64
+ # @!attribute status_code
65
+ # HTTP status code returned by the endpoint
66
+ #
67
+ # @return [Integer, nil]
68
+ required :status_code, Integer, api_name: :statusCode, nil?: true
69
+
70
+ # @!attribute success
71
+ # Whether the delivery was successful (2xx response)
72
+ #
73
+ # @return [Boolean]
74
+ required :success, ArkEmail::Internal::Type::Boolean
75
+
76
+ # @!attribute timestamp
77
+ # When this delivery attempt occurred
78
+ #
79
+ # @return [Time]
80
+ required :timestamp, Time
81
+
82
+ # @!attribute url
83
+ # URL the webhook was delivered to
84
+ #
85
+ # @return [String]
86
+ required :url, String
87
+
88
+ # @!attribute webhook_id
89
+ # ID of the webhook this delivery belongs to
90
+ #
91
+ # @return [String]
92
+ required :webhook_id, String, api_name: :webhookId
93
+
94
+ # @!attribute webhook_name
95
+ # Name of the webhook for easy identification
96
+ #
97
+ # @return [String]
98
+ required :webhook_name, String, api_name: :webhookName
99
+
100
+ # @!attribute will_retry
101
+ # Whether this delivery will be retried
102
+ #
103
+ # @return [Boolean]
104
+ required :will_retry, ArkEmail::Internal::Type::Boolean, api_name: :willRetry
105
+
106
+ # @!method initialize(id:, attempt:, event:, request:, response:, status_code:, success:, timestamp:, url:, webhook_id:, webhook_name:, will_retry:)
107
+ # Full details of a webhook delivery including request and response
108
+ #
109
+ # @param id [String] Unique delivery ID (UUID)
110
+ #
111
+ # @param attempt [Integer] Attempt number for this delivery
112
+ #
113
+ # @param event [Symbol, ArkEmail::Models::WebhookRetrieveDeliveryResponse::Data::Event] Event type that triggered this delivery
114
+ #
115
+ # @param request [ArkEmail::Models::WebhookRetrieveDeliveryResponse::Data::Request] The request that was sent to your endpoint
116
+ #
117
+ # @param response [ArkEmail::Models::WebhookRetrieveDeliveryResponse::Data::Response] The response received from your endpoint
118
+ #
119
+ # @param status_code [Integer, nil] HTTP status code returned by the endpoint
120
+ #
121
+ # @param success [Boolean] Whether the delivery was successful (2xx response)
122
+ #
123
+ # @param timestamp [Time] When this delivery attempt occurred
124
+ #
125
+ # @param url [String] URL the webhook was delivered to
126
+ #
127
+ # @param webhook_id [String] ID of the webhook this delivery belongs to
128
+ #
129
+ # @param webhook_name [String] Name of the webhook for easy identification
130
+ #
131
+ # @param will_retry [Boolean] Whether this delivery will be retried
132
+
133
+ # Event type that triggered this delivery
134
+ #
135
+ # @see ArkEmail::Models::WebhookRetrieveDeliveryResponse::Data#event
136
+ module Event
137
+ extend ArkEmail::Internal::Type::Enum
138
+
139
+ MESSAGE_SENT = :MessageSent
140
+ MESSAGE_DELAYED = :MessageDelayed
141
+ MESSAGE_DELIVERY_FAILED = :MessageDeliveryFailed
142
+ MESSAGE_HELD = :MessageHeld
143
+ MESSAGE_BOUNCED = :MessageBounced
144
+ MESSAGE_LINK_CLICKED = :MessageLinkClicked
145
+ MESSAGE_LOADED = :MessageLoaded
146
+ DOMAIN_DNS_ERROR = :DomainDNSError
147
+
148
+ # @!method self.values
149
+ # @return [Array<Symbol>]
150
+ end
151
+
152
+ # @see ArkEmail::Models::WebhookRetrieveDeliveryResponse::Data#request
153
+ class Request < ArkEmail::Internal::Type::BaseModel
154
+ # @!attribute headers
155
+ # HTTP headers that were sent with the request
156
+ #
157
+ # @return [Hash{Symbol=>String}]
158
+ required :headers, ArkEmail::Internal::Type::HashOf[String]
159
+
160
+ # @!attribute payload
161
+ # The complete webhook payload that was sent
162
+ #
163
+ # @return [Hash{Symbol=>Object}]
164
+ required :payload, ArkEmail::Internal::Type::HashOf[ArkEmail::Internal::Type::Unknown]
165
+
166
+ # @!method initialize(headers:, payload:)
167
+ # The request that was sent to your endpoint
168
+ #
169
+ # @param headers [Hash{Symbol=>String}] HTTP headers that were sent with the request
170
+ #
171
+ # @param payload [Hash{Symbol=>Object}] The complete webhook payload that was sent
172
+ end
173
+
174
+ # @see ArkEmail::Models::WebhookRetrieveDeliveryResponse::Data#response
175
+ class Response < ArkEmail::Internal::Type::BaseModel
176
+ # @!attribute status_code
177
+ # HTTP status code from your endpoint
178
+ #
179
+ # @return [Integer, nil]
180
+ required :status_code, Integer, api_name: :statusCode, nil?: true
181
+
182
+ # @!attribute body
183
+ # Response body from your endpoint (may be truncated)
184
+ #
185
+ # @return [String, nil]
186
+ optional :body, String, nil?: true
187
+
188
+ # @!method initialize(status_code:, body: nil)
189
+ # The response received from your endpoint
190
+ #
191
+ # @param status_code [Integer, nil] HTTP status code from your endpoint
192
+ #
193
+ # @param body [String, nil] Response body from your endpoint (may be truncated)
194
+ end
195
+ end
196
+ end
197
+ end
198
+ end
@@ -95,8 +95,14 @@ module ArkEmail
95
95
 
96
96
  WebhookDeleteParams = ArkEmail::Models::WebhookDeleteParams
97
97
 
98
+ WebhookListDeliveriesParams = ArkEmail::Models::WebhookListDeliveriesParams
99
+
98
100
  WebhookListParams = ArkEmail::Models::WebhookListParams
99
101
 
102
+ WebhookReplayDeliveryParams = ArkEmail::Models::WebhookReplayDeliveryParams
103
+
104
+ WebhookRetrieveDeliveryParams = ArkEmail::Models::WebhookRetrieveDeliveryParams
105
+
100
106
  WebhookRetrieveParams = ArkEmail::Models::WebhookRetrieveParams
101
107
 
102
108
  WebhookTestParams = ArkEmail::Models::WebhookTestParams
@@ -142,7 +142,7 @@ module ArkEmail
142
142
  # - `GET /emails/{id}/deliveries` - View delivery attempts
143
143
  # - `POST /emails/{id}/retry` - Retry failed delivery
144
144
  #
145
- # @overload send_(from:, subject:, to:, attachments: nil, bcc: nil, cc: nil, headers: nil, html: nil, reply_to: nil, tag: nil, text: nil, idempotency_key: nil, request_options: {})
145
+ # @overload send_(from:, subject:, to:, attachments: nil, bcc: nil, cc: nil, headers: nil, html: nil, metadata: nil, reply_to: nil, tag: nil, text: nil, idempotency_key: nil, request_options: {})
146
146
  #
147
147
  # @param from [String] Body param: Sender email address. Must be from a verified domain.
148
148
  #
@@ -160,6 +160,8 @@ module ArkEmail
160
160
  #
161
161
  # @param html [String, nil] Body param: HTML body content (accepts null).
162
162
  #
163
+ # @param metadata [Hash{Symbol=>String}, nil] Body param: Custom key-value pairs attached to an email for webhook correlation.
164
+ #
163
165
  # @param reply_to [String, nil] Body param: Reply-to address (accepts null)
164
166
  #
165
167
  # @param tag [String, nil] Body param: Tag for categorization and filtering (accepts null)
@@ -199,7 +201,7 @@ module ArkEmail
199
201
  #
200
202
  # @overload send_batch(emails:, from:, idempotency_key: nil, request_options: {})
201
203
  #
202
- # @param emails [Array<ArkEmail::Models::EmailSendBatchParams::Email>] Body param:
204
+ # @param emails [Array<ArkEmail::Models::EmailSendBatchParams::Email>] Body param
203
205
  #
204
206
  # @param from [String] Body param: Sender email for all messages
205
207
  #
@@ -129,6 +129,133 @@ module ArkEmail
129
129
  )
130
130
  end
131
131
 
132
+ # Get a paginated list of delivery attempts for a specific webhook.
133
+ #
134
+ # Use this to:
135
+ #
136
+ # - Monitor webhook health and delivery success rate
137
+ # - Debug failed deliveries
138
+ # - Find specific events to replay
139
+ #
140
+ # **Filtering:**
141
+ #
142
+ # - Filter by success/failure to find problematic deliveries
143
+ # - Filter by event type to find specific events
144
+ # - Filter by time range for debugging recent issues
145
+ #
146
+ # **Retry behavior:** Failed deliveries are automatically retried with exponential
147
+ # backoff over ~3 days. Check `willRetry` to see if more attempts are scheduled.
148
+ #
149
+ # @overload list_deliveries(webhook_id, after: nil, before: nil, event: nil, page: nil, per_page: nil, success: nil, request_options: {})
150
+ #
151
+ # @param webhook_id [String] Webhook ID or UUID
152
+ #
153
+ # @param after [Integer] Only deliveries after this Unix timestamp
154
+ #
155
+ # @param before [Integer] Only deliveries before this Unix timestamp
156
+ #
157
+ # @param event [Symbol, ArkEmail::Models::WebhookListDeliveriesParams::Event] Filter by event type
158
+ #
159
+ # @param page [Integer] Page number (default 1)
160
+ #
161
+ # @param per_page [Integer] Items per page (default 30, max 100)
162
+ #
163
+ # @param success [Boolean] Filter by delivery success (true = 2xx response, false = non-2xx or error)
164
+ #
165
+ # @param request_options [ArkEmail::RequestOptions, Hash{Symbol=>Object}, nil]
166
+ #
167
+ # @return [ArkEmail::Models::WebhookListDeliveriesResponse]
168
+ #
169
+ # @see ArkEmail::Models::WebhookListDeliveriesParams
170
+ def list_deliveries(webhook_id, params = {})
171
+ parsed, options = ArkEmail::WebhookListDeliveriesParams.dump_request(params)
172
+ @client.request(
173
+ method: :get,
174
+ path: ["webhooks/%1$s/deliveries", webhook_id],
175
+ query: parsed.transform_keys(per_page: "perPage"),
176
+ model: ArkEmail::Models::WebhookListDeliveriesResponse,
177
+ options: options
178
+ )
179
+ end
180
+
181
+ # Re-send a webhook delivery to your endpoint.
182
+ #
183
+ # **Use cases:**
184
+ #
185
+ # - Recover from transient failures after fixing your endpoint
186
+ # - Test endpoint changes with real historical data
187
+ # - Retry deliveries that failed due to downtime
188
+ #
189
+ # **How it works:**
190
+ #
191
+ # 1. Fetches the original payload from the delivery
192
+ # 2. Generates a new timestamp and signature
193
+ # 3. Sends to your webhook URL immediately
194
+ # 4. Returns the result (does not queue for retry if it fails)
195
+ #
196
+ # **Note:** The webhook must be enabled to replay deliveries.
197
+ #
198
+ # @overload replay_delivery(delivery_id, webhook_id:, request_options: {})
199
+ #
200
+ # @param delivery_id [String] Delivery ID (UUID) to replay
201
+ #
202
+ # @param webhook_id [String] Webhook ID or UUID
203
+ #
204
+ # @param request_options [ArkEmail::RequestOptions, Hash{Symbol=>Object}, nil]
205
+ #
206
+ # @return [ArkEmail::Models::WebhookReplayDeliveryResponse]
207
+ #
208
+ # @see ArkEmail::Models::WebhookReplayDeliveryParams
209
+ def replay_delivery(delivery_id, params)
210
+ parsed, options = ArkEmail::WebhookReplayDeliveryParams.dump_request(params)
211
+ webhook_id =
212
+ parsed.delete(:webhook_id) do
213
+ raise ArgumentError.new("missing required path argument #{_1}")
214
+ end
215
+ @client.request(
216
+ method: :post,
217
+ path: ["webhooks/%1$s/deliveries/%2$s/replay", webhook_id, delivery_id],
218
+ model: ArkEmail::Models::WebhookReplayDeliveryResponse,
219
+ options: options
220
+ )
221
+ end
222
+
223
+ # Get detailed information about a specific webhook delivery attempt.
224
+ #
225
+ # Returns:
226
+ #
227
+ # - The complete request payload that was sent
228
+ # - Request headers including the signature
229
+ # - Response status code and body from your endpoint
230
+ # - Timing information
231
+ #
232
+ # Use this to debug why a delivery failed or verify what data was sent.
233
+ #
234
+ # @overload retrieve_delivery(delivery_id, webhook_id:, request_options: {})
235
+ #
236
+ # @param delivery_id [String] Delivery ID (UUID)
237
+ #
238
+ # @param webhook_id [String] Webhook ID or UUID
239
+ #
240
+ # @param request_options [ArkEmail::RequestOptions, Hash{Symbol=>Object}, nil]
241
+ #
242
+ # @return [ArkEmail::Models::WebhookRetrieveDeliveryResponse]
243
+ #
244
+ # @see ArkEmail::Models::WebhookRetrieveDeliveryParams
245
+ def retrieve_delivery(delivery_id, params)
246
+ parsed, options = ArkEmail::WebhookRetrieveDeliveryParams.dump_request(params)
247
+ webhook_id =
248
+ parsed.delete(:webhook_id) do
249
+ raise ArgumentError.new("missing required path argument #{_1}")
250
+ end
251
+ @client.request(
252
+ method: :get,
253
+ path: ["webhooks/%1$s/deliveries/%2$s", webhook_id, delivery_id],
254
+ model: ArkEmail::Models::WebhookRetrieveDeliveryResponse,
255
+ options: options
256
+ )
257
+ end
258
+
132
259
  # Send a test payload to your webhook endpoint and verify it receives the data
133
260
  # correctly.
134
261
  #
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ArkEmail
4
- VERSION = "0.6.0"
4
+ VERSION = "0.8.0"
5
5
  end
data/lib/ark_email.rb CHANGED
@@ -106,8 +106,14 @@ require_relative "ark_email/models/webhook_create_params"
106
106
  require_relative "ark_email/models/webhook_create_response"
107
107
  require_relative "ark_email/models/webhook_delete_params"
108
108
  require_relative "ark_email/models/webhook_delete_response"
109
+ require_relative "ark_email/models/webhook_list_deliveries_params"
110
+ require_relative "ark_email/models/webhook_list_deliveries_response"
109
111
  require_relative "ark_email/models/webhook_list_params"
110
112
  require_relative "ark_email/models/webhook_list_response"
113
+ require_relative "ark_email/models/webhook_replay_delivery_params"
114
+ require_relative "ark_email/models/webhook_replay_delivery_response"
115
+ require_relative "ark_email/models/webhook_retrieve_delivery_params"
116
+ require_relative "ark_email/models/webhook_retrieve_delivery_response"
111
117
  require_relative "ark_email/models/webhook_retrieve_params"
112
118
  require_relative "ark_email/models/webhook_retrieve_response"
113
119
  require_relative "ark_email/models/webhook_test_params"
@@ -72,6 +72,28 @@ module ArkEmail
72
72
  sig { returns(T.nilable(String)) }
73
73
  attr_accessor :html
74
74
 
75
+ # Custom key-value pairs attached to an email for webhook correlation.
76
+ #
77
+ # When you send an email with metadata, these key-value pairs are:
78
+ #
79
+ # - **Stored** with the message
80
+ # - **Returned** in all webhook event payloads (MessageSent, MessageBounced, etc.)
81
+ # - **Never visible** to email recipients
82
+ #
83
+ # This is useful for correlating webhook events with your internal systems (e.g.,
84
+ # user IDs, order IDs, campaign identifiers).
85
+ #
86
+ # **Validation Rules:**
87
+ #
88
+ # - Maximum 10 keys per email
89
+ # - Keys: 1-40 characters, must start with a letter, only alphanumeric and
90
+ # underscores (`^[a-zA-Z][a-zA-Z0-9_]*$`)
91
+ # - Values: 1-500 characters, no control characters (newlines, tabs, etc.)
92
+ # - Total size: 4KB maximum (JSON-encoded)
93
+ sig { returns(T.nilable(T::Hash[Symbol, String])) }
94
+ attr_accessor :metadata
95
+
96
+ # Tag for categorization and filtering
75
97
  sig { returns(T.nilable(String)) }
76
98
  attr_accessor :tag
77
99
 
@@ -83,11 +105,38 @@ module ArkEmail
83
105
  subject: String,
84
106
  to: T::Array[String],
85
107
  html: T.nilable(String),
108
+ metadata: T.nilable(T::Hash[Symbol, String]),
86
109
  tag: T.nilable(String),
87
110
  text: T.nilable(String)
88
111
  ).returns(T.attached_class)
89
112
  end
90
- def self.new(subject:, to:, html: nil, tag: nil, text: nil)
113
+ def self.new(
114
+ subject:,
115
+ to:,
116
+ html: nil,
117
+ # Custom key-value pairs attached to an email for webhook correlation.
118
+ #
119
+ # When you send an email with metadata, these key-value pairs are:
120
+ #
121
+ # - **Stored** with the message
122
+ # - **Returned** in all webhook event payloads (MessageSent, MessageBounced, etc.)
123
+ # - **Never visible** to email recipients
124
+ #
125
+ # This is useful for correlating webhook events with your internal systems (e.g.,
126
+ # user IDs, order IDs, campaign identifiers).
127
+ #
128
+ # **Validation Rules:**
129
+ #
130
+ # - Maximum 10 keys per email
131
+ # - Keys: 1-40 characters, must start with a letter, only alphanumeric and
132
+ # underscores (`^[a-zA-Z][a-zA-Z0-9_]*$`)
133
+ # - Values: 1-500 characters, no control characters (newlines, tabs, etc.)
134
+ # - Total size: 4KB maximum (JSON-encoded)
135
+ metadata: nil,
136
+ # Tag for categorization and filtering
137
+ tag: nil,
138
+ text: nil
139
+ )
91
140
  end
92
141
 
93
142
  sig do
@@ -96,6 +145,7 @@ module ArkEmail
96
145
  subject: String,
97
146
  to: T::Array[String],
98
147
  html: T.nilable(String),
148
+ metadata: T.nilable(T::Hash[Symbol, String]),
99
149
  tag: T.nilable(String),
100
150
  text: T.nilable(String)
101
151
  }
@@ -54,6 +54,27 @@ module ArkEmail
54
54
  sig { returns(T.nilable(String)) }
55
55
  attr_accessor :html
56
56
 
57
+ # Custom key-value pairs attached to an email for webhook correlation.
58
+ #
59
+ # When you send an email with metadata, these key-value pairs are:
60
+ #
61
+ # - **Stored** with the message
62
+ # - **Returned** in all webhook event payloads (MessageSent, MessageBounced, etc.)
63
+ # - **Never visible** to email recipients
64
+ #
65
+ # This is useful for correlating webhook events with your internal systems (e.g.,
66
+ # user IDs, order IDs, campaign identifiers).
67
+ #
68
+ # **Validation Rules:**
69
+ #
70
+ # - Maximum 10 keys per email
71
+ # - Keys: 1-40 characters, must start with a letter, only alphanumeric and
72
+ # underscores (`^[a-zA-Z][a-zA-Z0-9_]*$`)
73
+ # - Values: 1-500 characters, no control characters (newlines, tabs, etc.)
74
+ # - Total size: 4KB maximum (JSON-encoded)
75
+ sig { returns(T.nilable(T::Hash[Symbol, String])) }
76
+ attr_accessor :metadata
77
+
57
78
  # Reply-to address (accepts null)
58
79
  sig { returns(T.nilable(String)) }
59
80
  attr_accessor :reply_to
@@ -84,6 +105,7 @@ module ArkEmail
84
105
  cc: T.nilable(T::Array[String]),
85
106
  headers: T.nilable(T::Hash[Symbol, String]),
86
107
  html: T.nilable(String),
108
+ metadata: T.nilable(T::Hash[Symbol, String]),
87
109
  reply_to: T.nilable(String),
88
110
  tag: T.nilable(String),
89
111
  text: T.nilable(String),
@@ -117,6 +139,25 @@ module ArkEmail
117
139
  # HTML body content (accepts null). Maximum 5MB (5,242,880 characters). Combined
118
140
  # with attachments, the total message must not exceed 14MB.
119
141
  html: nil,
142
+ # Custom key-value pairs attached to an email for webhook correlation.
143
+ #
144
+ # When you send an email with metadata, these key-value pairs are:
145
+ #
146
+ # - **Stored** with the message
147
+ # - **Returned** in all webhook event payloads (MessageSent, MessageBounced, etc.)
148
+ # - **Never visible** to email recipients
149
+ #
150
+ # This is useful for correlating webhook events with your internal systems (e.g.,
151
+ # user IDs, order IDs, campaign identifiers).
152
+ #
153
+ # **Validation Rules:**
154
+ #
155
+ # - Maximum 10 keys per email
156
+ # - Keys: 1-40 characters, must start with a letter, only alphanumeric and
157
+ # underscores (`^[a-zA-Z][a-zA-Z0-9_]*$`)
158
+ # - Values: 1-500 characters, no control characters (newlines, tabs, etc.)
159
+ # - Total size: 4KB maximum (JSON-encoded)
160
+ metadata: nil,
120
161
  # Reply-to address (accepts null)
121
162
  reply_to: nil,
122
163
  # Tag for categorization and filtering (accepts null)
@@ -141,6 +182,7 @@ module ArkEmail
141
182
  cc: T.nilable(T::Array[String]),
142
183
  headers: T.nilable(T::Hash[Symbol, String]),
143
184
  html: T.nilable(String),
185
+ metadata: T.nilable(T::Hash[Symbol, String]),
144
186
  reply_to: T.nilable(String),
145
187
  tag: T.nilable(String),
146
188
  text: T.nilable(String),