zapsmtp 0.1.0.beta3

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.
@@ -0,0 +1,2818 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Generated by sdks/codegen. Do not edit: run node sdks/codegen/generate.mjs.
4
+
5
+ module ZapSMTP
6
+ # The API's resources, one class per path of zap.<resource>.
7
+ module Resources
8
+ # zap.emails.receiving.attachments
9
+ class EmailsReceivingAttachments
10
+ # @api private
11
+ def initialize(client)
12
+ @client = client
13
+ end
14
+
15
+ # List attachments.
16
+ #
17
+ # List a received email's attachments with signed download links. Requires a full-access key. Each
18
+ # download_url works for one hour without an API key. Files are always served as downloads; HTML, SVG,
19
+ # XML and JavaScript are served as binary so they can never run in a browser.
20
+ #
21
+ # @param id [String] Received email id
22
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
23
+ # @option params [Integer] :limit 1-100; when omitted or out of range all attachments are returned.
24
+ # @option params [String] :after Attachment id; returns attachments after it (ignored if unknown).
25
+ # @option params [String] :before Attachment id; returns attachments before it (used only when after is
26
+ # absent).
27
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
28
+ # @return [ZapSMTP::Page<ZapSMTP::Models::Attachment>]
29
+ def list(id, params = {}, request_options: {}, **kwargs)
30
+ @client.request_page(
31
+ method: :get,
32
+ path: "/emails/receiving/#{Util.seg("id", id)}/attachments",
33
+ query: Util.params(params, kwargs),
34
+ model: Models::Attachment,
35
+ paging: :after,
36
+ request_options: request_options
37
+ )
38
+ end
39
+
40
+ # Retrieve an attachment.
41
+ #
42
+ # Retrieve one attachment's metadata and signed download link. Requires a full-access key.
43
+ #
44
+ # @param id [String] Received email id
45
+ # @param aid [String] Attachment id
46
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
47
+ # @return [ZapSMTP::Models::Attachment]
48
+ def get(id, aid, request_options: {})
49
+ @client.request(
50
+ method: :get,
51
+ path: "/emails/receiving/#{Util.seg("id", id)}/attachments/#{Util.seg("aid", aid)}",
52
+ model: Models::Attachment,
53
+ request_options: request_options
54
+ )
55
+ end
56
+ end
57
+
58
+ # zap.emails.receiving
59
+ class EmailsReceiving
60
+ # @return [EmailsReceivingAttachments]
61
+ attr_reader :attachments
62
+
63
+ # @api private
64
+ def initialize(client)
65
+ @client = client
66
+ @attachments = EmailsReceivingAttachments.new(client)
67
+ end
68
+
69
+ # List received emails.
70
+ #
71
+ # List received (inbound) emails, newest first. Requires a full-access key. action is default, webhook,
72
+ # store, reject or spam_reject. in_reply_to_email_id appears only when the message replies to an email
73
+ # you sent through ZapSMTP.
74
+ #
75
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
76
+ # @option params [Integer] :limit 1-100; out-of-range falls back to 20. Default: 20.
77
+ # @option params [String] :before Cursor: an email id or RFC 3339 time; returns messages received before
78
+ # it. An email id gives an exact page boundary. Limits: 422 invalid_parameter "before must be an email
79
+ # id or RFC 3339 time"
80
+ # @option params [String] :after Email id or RFC 3339 time. Limits: 422 invalid_parameter "after must be
81
+ # an email id or RFC 3339 time"
82
+ # @option params [String] :q Case-insensitive substring of sender, recipient or subject, or an exact id.
83
+ # @option params [String] :status One of: received, rejected.
84
+ # @option params [String] :domain Inbound domain name (exact).
85
+ # @option params [String] :thread_id Only emails of this conversation (see GET /threads/{id}).
86
+ # @option params [String] :automated false: only emails a person wrote; true: only automated ones; or
87
+ # one type: bounce, out_of_office, auto_reply, auto_generated, bulk. Limits: 422 invalid_parameter for
88
+ # other values.
89
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
90
+ # @return [ZapSMTP::Page<ZapSMTP::Models::ReceivedEmail>]
91
+ def list(params = {}, request_options: {}, **kwargs)
92
+ @client.request_page(
93
+ method: :get,
94
+ path: "/emails/receiving",
95
+ query: Util.params(params, kwargs),
96
+ model: Models::ReceivedEmail,
97
+ paging: :before,
98
+ request_options: request_options
99
+ )
100
+ end
101
+
102
+ # Retrieve a received email.
103
+ #
104
+ # Retrieve a received email with bodies, headers, authentication results and download links. Requires a
105
+ # full-access key. automated is null for mail a person wrote, else {type, reason}: bounce (delivery
106
+ # status notification), out_of_office, auto_reply, auto_generated (notifications, null sender) or bulk
107
+ # (mailing lists). Detected from Auto-Submitted, X-Autoreply, Precedence, List-Id, multipart/report and
108
+ # well-known subjects; reason names the evidence. tls: the TLS version the sending server used (e.g.
109
+ # TLSv1_3); empty when the message was not encrypted.
110
+ #
111
+ # @param id [String] Received email id
112
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
113
+ # @option params [String] :html_format cid: return html as received (cid: references to inline parts).
114
+ # Any other value: inline images are embedded as data: URIs (html_format in the response reports what
115
+ # was returned). One of: data_uri, cid. Default: data_uri.
116
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
117
+ # @return [ZapSMTP::Models::ReceivedEmail]
118
+ def get(id, params = {}, request_options: {}, **kwargs)
119
+ @client.request(
120
+ method: :get,
121
+ path: "/emails/receiving/#{Util.seg("id", id)}",
122
+ query: Util.params(params, kwargs),
123
+ model: Models::ReceivedEmail,
124
+ request_options: request_options
125
+ )
126
+ end
127
+
128
+ # Delete a received email.
129
+ #
130
+ # Permanently erase a received email's content and metadata (GDPR erasure). Requires a full-access live
131
+ # key; test keys get 403 test_key_restricted. Idempotent: deleting an id that does not exist (but is a
132
+ # valid UUID) still returns 200 deleted:true.
133
+ #
134
+ # @param id [String] Received email id
135
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
136
+ # @return [ZapSMTP::Models::Deleted]
137
+ def delete(id, request_options: {})
138
+ @client.request(
139
+ method: :delete,
140
+ path: "/emails/receiving/#{Util.seg("id", id)}",
141
+ model: Models::Deleted,
142
+ request_options: request_options
143
+ )
144
+ end
145
+
146
+ # Redeliver to webhooks.
147
+ #
148
+ # Re-send the email.received webhook for a stored message. Requires a full-access live key; test keys
149
+ # get 403 test_key_restricted. The event is re-queued asynchronously (hence 202).
150
+ #
151
+ # @param id [String] Received email id
152
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
153
+ # @return [ZapSMTP::Models::ReceivedEmailAction]
154
+ def redeliver(id, request_options: {})
155
+ @client.request(
156
+ method: :post,
157
+ path: "/emails/receiving/#{Util.seg("id", id)}/redeliver",
158
+ model: Models::ReceivedEmailAction,
159
+ request_options: request_options
160
+ )
161
+ end
162
+
163
+ # Report spam / not spam.
164
+ #
165
+ # Report a received email as spam or not spam: your account's spam filter learns from it. Requires a
166
+ # full-access live key; test keys get 403 test_key_restricted. Each account has its own statistics: your
167
+ # reports never change another account's filter. The filter starts scoring once it has learned 20 emails
168
+ # of each kind. Reporting the same email twice is harmless. learned is false when the email has too few
169
+ # words to learn from.
170
+ #
171
+ # @param id [String] Received email id.
172
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
173
+ # @option params [Boolean] :spam true: mail like this is spam; false: it is wanted. Limits: missing →
174
+ # 422 missing_required_field Required.
175
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
176
+ # @return [ZapSMTP::Models::ReceivedEmailAction]
177
+ def report_spam(id, params = {}, request_options: {}, **kwargs)
178
+ @client.request(
179
+ method: :post,
180
+ path: "/emails/receiving/#{Util.seg("id", id)}/spam",
181
+ body: Util.params(params, kwargs),
182
+ model: Models::ReceivedEmailAction,
183
+ request_options: request_options
184
+ )
185
+ end
186
+
187
+ # Reply to a received email.
188
+ #
189
+ # Reply to a received email: recipients, subject, sender and threading headers default to the email's,
190
+ # so the answer lands in the sender's conversation. Requires a full-access key. Live keys: the From
191
+ # domain must be verified for sending. Our Message-ID of the reply names its thread, so the customer's
192
+ # answer joins the conversation even from a mail client that keeps only In-Reply-To. Every other rule of
193
+ # POST /emails applies: suppressions, quotas, tracking, test keys. Loop protection: replies to automated
194
+ # email need allow_automated, and one conversation takes at most 20 replies an hour.
195
+ #
196
+ # @param id [String] Received email id
197
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
198
+ # @option params [String] :text Plain-text body. Either text or html (or a template) is required.
199
+ # @option params [String] :html HTML body.
200
+ # @option params [String] :from Default: the address that received the email (e.g. support@acme.com),
201
+ # which must be on a verified sending domain. Required when the email came to a managed *.in.zapsmtp.com
202
+ # address (those only receive): 422 missing_required_field.
203
+ # @option params [String, Array<String>] :to Default: the email's Reply-To, else its From. Limits: 422
204
+ # missing_required_field when the email has neither.
205
+ # @option params [Boolean] :reply_all Also copy everyone on the email's To and Cc, except the receiving
206
+ # address, the sender you reply from and anyone already addressed. Default: false.
207
+ # @option params [Boolean] :allow_automated Answer an automated email anyway (see automated on the
208
+ # received email). Without it a reply to a bounce, out-of-office, auto-reply or notification is refused
209
+ # with 422 automated_message: two auto-responders answering each other is a mail loop. Bulk mail can be
210
+ # answered without it. Default: false.
211
+ # @option params [Boolean] :auto_reply This answer is itself automatic (an acknowledgement, a ticket
212
+ # receipt): adds Auto-Submitted: auto-replied and X-Auto-Response-Suppress: All (RFC 3834), so other
213
+ # auto-responders do not answer it. Default: false.
214
+ # @option params [String, Array<String>] :cc Added to the Cc (reply_all adds the email's recipients
215
+ # after these).
216
+ # @option params [String, Array<String>] :bcc Bcc recipients.
217
+ # @option params [String, Array<String>] :reply_to Default: the receiving address when you reply from
218
+ # another one, so the customer's answer comes back to the same inbox.
219
+ # @option params [String] :subject Default: Re: + the email's subject (kept as is when it already starts
220
+ # with Re:).
221
+ # @option params [Hash{String => String}] :headers Custom headers. In-Reply-To and References are set
222
+ # for you (RFC 5322 threading); a value you give wins.
223
+ # @option params [Array<Hash>] :attachments Attachments; 40 MB total. Limits: 422 invalid_attachment
224
+ # with message attachments[i]: set either content or path, not both | content must be base64 | content
225
+ # or path is required | filename is required | path must be an http(s) URL | fetching path returned HTTP
226
+ # <n> | attachments exceed 40MB in total
227
+ # @option params [Array<Hash>] :tags Returned in webhooks as data.tags. Limits: at most 20 tags per
228
+ # email; name and value must match ^[A-Za-z0-9_-]{1,256}$ (422 invalid_parameter)
229
+ # @option params [Hash{String => String}] :metadata Returned in webhooks and GET /emails; filter with
230
+ # GET /emails?metadata[key]=value. Limits: max 10 keys; keys ^[A-Za-z0-9_-]{1,40}$; values max 500 bytes
231
+ # (UTF-8) (422 invalid_parameter)
232
+ # @option params [String] :stream Limits: other values → 422 invalid_parameter; conflicting with the
233
+ # key's stream → 403 restricted_api_key One of: transactional, broadcast. Default: transactional (or the
234
+ # key's stream).
235
+ # @option params [Hash] :tracking Overrides the From domain's open, click and reply tracking defaults
236
+ # for this email.
237
+ # @option params [Hash] :template Render a stored, published template: id = template id or alias.
238
+ # Request subject/from override the template's. Cannot be combined with html/text. Limits: missing id →
239
+ # 422 missing_required_field "template.id is required"; unknown → 422 invalid_parameter "template <id>
240
+ # not found"; never published → 422 invalid_parameter; variables.global → 422 invalid_parameter
241
+ # (reserved); a value of the wrong type → 422 template_variables_invalid; a required variable without
242
+ # value or default → 422 template_variables_missing; anything else the template uses still absent → 422
243
+ # template_render_error "missing template variables: a, b"
244
+ # @option params [String] :scheduled_at RFC 3339 time (e.g. 2026-10-21T15:00:00Z) or relative "in <n>
245
+ # <unit>" with unit min|mins|minute|minutes|h|hour|hours|d|day|days. Times in the past send immediately.
246
+ # Limits: unparsable → 422 invalid_parameter; more than 7 days ahead → 422 invalid_parameter
247
+ # "scheduled_at must be within 7 days"
248
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
249
+ # @return [ZapSMTP::Models::SendEmailResponse]
250
+ def reply(id, params = {}, request_options: {}, **kwargs)
251
+ @client.request(
252
+ method: :post,
253
+ path: "/emails/receiving/#{Util.seg("id", id)}/reply",
254
+ body: Util.params(params, kwargs),
255
+ idempotent: true,
256
+ model: Models::SendEmailResponse,
257
+ request_options: request_options
258
+ )
259
+ end
260
+ end
261
+
262
+ # zap.emails.attachments
263
+ class EmailsAttachments
264
+ # @api private
265
+ def initialize(client)
266
+ @client = client
267
+ end
268
+
269
+ # List attachments.
270
+ #
271
+ # Attachments of a sent email, each with a download link valid for one hour. Requires a full-access key.
272
+ # Emails sent without attachments return an empty list.
273
+ #
274
+ # @param id [String] Email id.
275
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
276
+ # @return [ZapSMTP::Page<ZapSMTP::Models::Attachment>]
277
+ def list(id, request_options: {})
278
+ @client.request_page(
279
+ method: :get,
280
+ path: "/emails/#{Util.seg("id", id)}/attachments",
281
+ model: Models::Attachment,
282
+ paging: nil,
283
+ request_options: request_options
284
+ )
285
+ end
286
+
287
+ # Retrieve an attachment.
288
+ #
289
+ # One attachment of a sent email with a fresh download link. Requires a full-access key.
290
+ #
291
+ # @param id [String] Email id.
292
+ # @param aid [String] Attachment id from the list.
293
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
294
+ # @return [ZapSMTP::Models::Attachment]
295
+ def get(id, aid, request_options: {})
296
+ @client.request(
297
+ method: :get,
298
+ path: "/emails/#{Util.seg("id", id)}/attachments/#{Util.seg("aid", aid)}",
299
+ model: Models::Attachment,
300
+ request_options: request_options
301
+ )
302
+ end
303
+ end
304
+
305
+ # zap.emails
306
+ class Emails
307
+ # @return [EmailsReceiving]
308
+ attr_reader :receiving
309
+
310
+ # @return [EmailsAttachments]
311
+ attr_reader :attachments
312
+
313
+ # @api private
314
+ def initialize(client)
315
+ @client = client
316
+ @receiving = EmailsReceiving.new(client)
317
+ @attachments = EmailsAttachments.new(client)
318
+ end
319
+
320
+ # Send an email.
321
+ #
322
+ # Send an email (or schedule it with scheduled_at). Requires a full-access or sending-access key. Live
323
+ # keys: From domain must be verified by the account. Test keys: any From domain, nothing delivered,
324
+ # monthly quota not charged. Recipients are deduplicated and lowercased; max 50 across to+cc+bcc.
325
+ # Message-ID is <id>@<hostname>, or <id>.<thread_id>@<hostname> for a reply that continues a
326
+ # conversation. The response also carries thread_id: the conversation this email belongs to. An email
327
+ # with In-Reply-To / References headers (set them in headers) joins the thread of the message it
328
+ # answers; otherwise it starts a new one. failed_recipients: addresses the mail server refused while it
329
+ # took the others; they are not sent and not charged. unconfirmed: true: the mail server took the
330
+ # message but its answer was lost; it counts as sent and must not be retried (its events tell the
331
+ # outcome). Scheduled emails (scheduled_at): at most 10,000 (256 MB) may wait per account. At send time
332
+ # the account and the key are checked again: a suspended account or a revoked or expired key fails the
333
+ # email. With reply tracking on, the response carries reply_to: the tracked address the email carries in
334
+ # place of its own Reply-To. Human replies are forwarded to the domain’s reply_forward_to, else to the
335
+ # email’s first Reply-To, else to its From.
336
+ #
337
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
338
+ # @option params [String] :from RFC 5322 address, e.g. "Acme <hello@acme.com>". Domain must be verified
339
+ # (live keys). When only an address is given, the domain's from_name (brand settings) is used as display
340
+ # name. May be omitted when template is used and the template defines from. Limits: missing → 422
341
+ # missing_required_field; unparsable → 422 invalid_parameter "invalid from address"
342
+ # @option params [String, Array<String>] :to Recipient(s). Limits: at least one; each must parse as an
343
+ # address (422 invalid_parameter "invalid to address ...") Required.
344
+ # @option params [String, Array<String>] :cc Cc recipients.
345
+ # @option params [String, Array<String>] :bcc Bcc recipients.
346
+ # @option params [String, Array<String>] :reply_to Reply-To address(es).
347
+ # @option params [String] :subject Subject line. May be omitted when template is used and the template
348
+ # defines a subject. Limits: blank → 422 missing_required_field
349
+ # @option params [String] :html HTML body. At least one of html/text is required (unless template is
350
+ # used). Limits: both empty → 422 missing_required_field "html or text is required"; cannot be combined
351
+ # with template (422 invalid_parameter)
352
+ # @option params [String] :text Plain-text body. When only html is given, a plain-text part is generated
353
+ # from it (readable text, links as text (url), hidden elements such as the preheader left out).
354
+ # @option params [Hash{String => String}] :headers Custom headers. Limits: Reserved headers are rejected
355
+ # (422 invalid_parameter "header ... cannot be set"): From, To, Cc, Bcc, Reply-To, Subject, Date,
356
+ # Message-Id, Mime-Version, Content-Type, Content-Transfer-Encoding, DKIM-Signature, Return-Path,
357
+ # Received, any X-Zap-*, X-ZapRef. Names must be printable ASCII without spaces or ':'.
358
+ # @option params [Array<Hash>] :attachments Attachments; 40 MB total. Limits: 422 invalid_attachment
359
+ # with message attachments[i]: set either content or path, not both | content must be base64 | content
360
+ # or path is required | filename is required | path must be an http(s) URL | fetching path returned HTTP
361
+ # <n> | attachments exceed 40MB in total
362
+ # @option params [Array<Hash>] :tags Returned in webhooks as data.tags. Limits: at most 20 tags per
363
+ # email; name and value must match ^[A-Za-z0-9_-]{1,256}$ (422 invalid_parameter)
364
+ # @option params [String] :scheduled_at RFC 3339 time (e.g. 2026-10-21T15:00:00Z) or relative "in <n>
365
+ # <unit>" with unit min|mins|minute|minutes|h|hour|hours|d|day|days. Times in the past send immediately.
366
+ # Limits: unparsable → 422 invalid_parameter; more than 7 days ahead → 422 invalid_parameter
367
+ # "scheduled_at must be within 7 days"
368
+ # @option params [Hash{String => String}] :metadata Returned in webhooks and GET /emails; filter with
369
+ # GET /emails?metadata[key]=value. Limits: max 10 keys; keys ^[A-Za-z0-9_-]{1,40}$; values max 500 bytes
370
+ # (UTF-8) (422 invalid_parameter)
371
+ # @option params [String] :stream Limits: other values → 422 invalid_parameter; conflicting with the
372
+ # key's stream → 403 restricted_api_key One of: transactional, broadcast. Default: transactional (or the
373
+ # key's stream).
374
+ # @option params [Hash] :tracking Overrides the From domain's open, click and reply tracking defaults
375
+ # for this email.
376
+ # @option params [Hash] :template Render a stored, published template: id = template id or alias.
377
+ # Request subject/from override the template's. Cannot be combined with html/text. Limits: missing id →
378
+ # 422 missing_required_field "template.id is required"; unknown → 422 invalid_parameter "template <id>
379
+ # not found"; never published → 422 invalid_parameter; variables.global → 422 invalid_parameter
380
+ # (reserved); a value of the wrong type → 422 template_variables_invalid; a required variable without
381
+ # value or default → 422 template_variables_missing; anything else the template uses still absent → 422
382
+ # template_render_error "missing template variables: a, b"
383
+ # @option params [String] :tls required or verified: deliver only over TLS (verified: with a valid
384
+ # certificate for the receiving server). Raises the domain's policy, never lowers it.
385
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
386
+ # @return [ZapSMTP::Models::SendEmailResponse]
387
+ def send(params = {}, request_options: {}, **kwargs)
388
+ @client.request(
389
+ method: :post,
390
+ path: "/emails",
391
+ body: Util.params(params, kwargs),
392
+ idempotent: true,
393
+ model: Models::SendEmailResponse,
394
+ request_options: request_options
395
+ )
396
+ end
397
+
398
+ # Send a batch.
399
+ #
400
+ # Send 1-100 emails in one request. Requires a full-access or sending-access key. Test keys follow the
401
+ # same rules as for sending. Per-email error codes use the same classification as POST /emails
402
+ # (domain_not_verified, restricted_api_key, rate_limit_exceeded, monthly_quota_exceeded, etc. appear
403
+ # inside errors[] rather than as the HTTP status). Emails are sent concurrently (up to 16 at a time);
404
+ # each email may have its own scheduled_at. Body: length 1-100 else 422 invalid_parameter "batch must
405
+ # contain 1 to 100 emails" An item of data carries reply_to when reply tracking is on for that email.
406
+ #
407
+ # @param emails [Array<Hash>] the emails, each with the parameters of emails.send
408
+ # @param validation [String, nil] strict (default) | permissive (case-insensitive). strict: if any email
409
+ # fails validation nothing is sent and 422 is returned. permissive: valid emails are sent; invalid ones
410
+ # are reported in errors.
411
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
412
+ # @return [ZapSMTP::Models::SendBatchResponse]
413
+ def send_batch(emails, validation: nil, request_options: {})
414
+ @client.request(
415
+ method: :post,
416
+ path: "/emails/batch",
417
+ body: emails,
418
+ headers: { "x-batch-validation" => validation },
419
+ idempotent: true,
420
+ model: Models::SendBatchResponse,
421
+ request_options: request_options
422
+ )
423
+ end
424
+
425
+ # List emails.
426
+ #
427
+ # List sent emails, newest first. Requires a full-access key. Use the last item's id as before= for the
428
+ # next page. metadata may be null when the email has none. last_status and last_event carry the same
429
+ # value.
430
+ #
431
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
432
+ # @option params [Integer] :limit 1-100; out-of-range values fall back to 20. Default: 20.
433
+ # @option params [String] :before Cursor: an email id (UUIDv7) or RFC 3339 time; returns emails accepted
434
+ # before it. An email id gives an exact page boundary. Limits: 422 invalid_parameter "before must be an
435
+ # email id or RFC 3339 time"
436
+ # @option params [String] :after Email id or RFC 3339 time; only emails created after it (still newest
437
+ # first). Limits: 422 invalid_parameter "after must be an email id or RFC 3339 time"
438
+ # @option params [String] :status Filter by latest status. status=scheduled lists pending scheduled
439
+ # sends instead (different item shape, ordered by scheduled time ascending, has_more always false, other
440
+ # filters/cursors ignored). One of: queued, delivered, delivery_delayed, bounced, complained, failed,
441
+ # opened, clicked, replied, suppressed, scheduled.
442
+ # @option params [String] :q Case-insensitive substring of a recipient or subject, or an exact email id.
443
+ # @option params [Integer] :days Look-back window in days, 1-90 (other values ignored). Always capped by
444
+ # the plan's log retention. Default: 30.
445
+ # @option params [String] :stream One of: transactional, broadcast.
446
+ # @option params [String] :mode Filter live or test-mode (sandbox) traffic; other values ignored. One
447
+ # of: live, test.
448
+ # @option params [Hash{String => String}] :metadata Exact match on a metadata value, e.g.
449
+ # metadata[order_id]=A-1042. Repeatable for several keys.
450
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
451
+ # @return [ZapSMTP::Page<ZapSMTP::Models::Email>]
452
+ def list(params = {}, request_options: {}, **kwargs)
453
+ @client.request_page(
454
+ method: :get,
455
+ path: "/emails",
456
+ query: Util.params(params, kwargs),
457
+ model: Models::Email,
458
+ paging: :before,
459
+ request_options: request_options
460
+ )
461
+ end
462
+
463
+ # Retrieve an email.
464
+ #
465
+ # Retrieve one email with per-recipient status and its event timeline. Requires a full-access key. Only
466
+ # data inside the plan's log retention is visible. metadata may be null.
467
+ #
468
+ # @param id [String] Email id
469
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
470
+ # @return [ZapSMTP::Models::Email]
471
+ def get(id, request_options: {})
472
+ @client.request(
473
+ method: :get,
474
+ path: "/emails/#{Util.seg("id", id)}",
475
+ model: Models::Email,
476
+ request_options: request_options
477
+ )
478
+ end
479
+
480
+ # Reschedule an email.
481
+ #
482
+ # Reschedule a scheduled email. Requires a full-access or sending-access key. Unknown ids return 409
483
+ # not_cancellable, not 404.
484
+ #
485
+ # @param id [String] Scheduled email id
486
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
487
+ # @option params [String] :scheduled_at RFC 3339 or "in <n> <unit>" (see POST /emails). A time in the
488
+ # past dispatches as soon as possible. Limits: missing → 422 missing_required_field; unparsable or > 7
489
+ # days ahead → 422 invalid_parameter Required.
490
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
491
+ # @return [ZapSMTP::Models::Email]
492
+ def update(id, params = {}, request_options: {}, **kwargs)
493
+ @client.request(
494
+ method: :patch,
495
+ path: "/emails/#{Util.seg("id", id)}",
496
+ body: Util.params(params, kwargs),
497
+ model: Models::Email,
498
+ request_options: request_options
499
+ )
500
+ end
501
+
502
+ # Cancel a scheduled email.
503
+ #
504
+ # Cancel a scheduled email before it is dispatched. Requires a full-access or sending-access key.
505
+ #
506
+ # @param id [String] Scheduled email id
507
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
508
+ # @return [ZapSMTP::Models::Email]
509
+ def cancel(id, request_options: {})
510
+ @client.request(
511
+ method: :post,
512
+ path: "/emails/#{Util.seg("id", id)}/cancel",
513
+ model: Models::Email,
514
+ request_options: request_options
515
+ )
516
+ end
517
+
518
+ # Retrieve email content.
519
+ #
520
+ # Retrieve the archived content of a sent email. Requires a full-access key. source is api or smtp; tags
521
+ # is the URL-encoded tag string. Content is kept for your plan’s log retention.
522
+ #
523
+ # @param id [String] Email id
524
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
525
+ # @return [ZapSMTP::Models::EmailContent]
526
+ def get_content(id, request_options: {})
527
+ @client.request(
528
+ method: :get,
529
+ path: "/emails/#{Util.seg("id", id)}/content",
530
+ model: Models::EmailContent,
531
+ request_options: request_options
532
+ )
533
+ end
534
+
535
+ # Spam-check a draft.
536
+ #
537
+ # Score a draft for spam before sending (nothing is sent or stored). Requires a full-access or
538
+ # sending-access key. Body: from missing or both html and text empty → 422 missing_required_field "from
539
+ # and html or text are required". Only these six fields are accepted (others → 400).
540
+ #
541
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
542
+ # @option params [String] :from From address; when its domain is verified by the account the draft is
543
+ # DKIM-signed with the real key. Required.
544
+ # @option params [String, Array<String>] :to Recipient(s); the first is used as envelope recipient.
545
+ # Limits: 422 invalid_parameter "to must be a string or an array of strings" Default:
546
+ # recipient@example.com.
547
+ # @option params [String] :subject
548
+ # @option params [String] :html At least one of html and text is required.
549
+ # @option params [String] :text
550
+ # @option params [String] :stream Selects the shared pool used to pick the egress IP when the account
551
+ # has no dedicated IP. Default: transactional.
552
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
553
+ # @return [ZapSMTP::Models::SpamCheck]
554
+ def spam_check(params = {}, request_options: {}, **kwargs)
555
+ @client.request(
556
+ method: :post,
557
+ path: "/emails/spam-check",
558
+ body: Util.params(params, kwargs),
559
+ model: Models::SpamCheck,
560
+ request_options: request_options
561
+ )
562
+ end
563
+
564
+ # Spam-check a sent email.
565
+ #
566
+ # Score an already sent email (live or test) from the content archive. Requires a full-access key.
567
+ # Always scored with the transactional pool's IP when the account has no dedicated IP. Availability
568
+ # follows GET /emails/{id}/content (plan log retention), although the 404 message says 7 days.
569
+ #
570
+ # @param id [String] Email id
571
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
572
+ # @return [ZapSMTP::Models::SpamCheck]
573
+ def spam_check_sent(id, request_options: {})
574
+ @client.request(
575
+ method: :post,
576
+ path: "/emails/#{Util.seg("id", id)}/spam-check",
577
+ model: Models::SpamCheck,
578
+ request_options: request_options
579
+ )
580
+ end
581
+
582
+ # Share an email.
583
+ #
584
+ # Create a link anyone can open to view a sent email — for a colleague or support. It shows the subject,
585
+ # sender, recipients and body; never attachments or headers. Requires a full-access live key; test keys
586
+ # get 403 test_key_restricted. The page renders the body in a sandbox: scripts, forms and external
587
+ # requests other than images are blocked.
588
+ #
589
+ # @param id [String] Email id.
590
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
591
+ # @option params [Integer] :expires_in_hours 1–720. Default: 72.
592
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
593
+ # @return [ZapSMTP::Models::EmailShare]
594
+ def share(id, params = {}, request_options: {}, **kwargs)
595
+ @client.request(
596
+ method: :post,
597
+ path: "/emails/#{Util.seg("id", id)}/share",
598
+ body: Util.params(params, kwargs),
599
+ model: Models::EmailShare,
600
+ request_options: request_options
601
+ )
602
+ end
603
+ end
604
+
605
+ # zap.threads
606
+ class Threads
607
+ # @api private
608
+ def initialize(client)
609
+ @client = client
610
+ end
611
+
612
+ # List conversations.
613
+ #
614
+ # List conversations (threads with at least one received email), the most recently active first: a
615
+ # helpdesk inbox. Requires a full-access key. Served from a per-conversation summary kept up to date as
616
+ # emails arrive: a page costs the same however much email you have. A conversation you started (your
617
+ # first email) is counted once the customer answers it.
618
+ #
619
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
620
+ # @option params [Integer] :limit 1-100; out-of-range falls back to 20. Default: 20.
621
+ # @option params [String] :before Cursor: the last_message_at of the last conversation you have (RFC
622
+ # 3339). Limits: 422 invalid_parameter otherwise.
623
+ # @option params [String] :before_id With before: the id of the last conversation you have, so
624
+ # conversations active at the same instant are neither skipped nor repeated.
625
+ # @option params [Boolean] :awaiting_reply true: only conversations whose last human email came in.
626
+ # @option params [Boolean] :unread true: only conversations with an email received after their read
627
+ # mark.
628
+ # @option params [String] :participant Only conversations this address took part in (case-insensitive).
629
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
630
+ # @return [ZapSMTP::Page<ZapSMTP::Models::Thread>]
631
+ def list(params = {}, request_options: {}, **kwargs)
632
+ @client.request_page(
633
+ method: :get,
634
+ path: "/threads",
635
+ query: Util.params(params, kwargs),
636
+ model: Models::Thread,
637
+ paging: :thread,
638
+ request_options: request_options
639
+ )
640
+ end
641
+
642
+ # Retrieve a conversation.
643
+ #
644
+ # A conversation: its state (participants, counts, last message, awaiting_reply, unread, metadata) and
645
+ # its received and sent emails, oldest first. Requires a full-access key. awaiting_reply: the last email
646
+ # a person wrote came in (automated mail does not count). unread: something was received after read_at
647
+ # (set with PATCH /threads/{id}). Threads are derived from the standard In-Reply-To / References
648
+ # headers: no setup. Every received email, webhook email.received and send response carries its
649
+ # thread_id. Refused messages are not part of a thread. At most 500 emails are listed (has_more); fetch
650
+ # bodies with GET /emails/receiving/{id} and GET /emails/{id}/content. Emails received before 2026-10-23
651
+ # have a thread id but are not listed here.
652
+ #
653
+ # @param id [String] Thread id (thread_id of any email in it)
654
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
655
+ # @return [ZapSMTP::Models::Thread]
656
+ def get(id, request_options: {})
657
+ @client.request(
658
+ method: :get,
659
+ path: "/threads/#{Util.seg("id", id)}",
660
+ model: Models::Thread,
661
+ request_options: request_options
662
+ )
663
+ end
664
+
665
+ # Mark read, set metadata.
666
+ #
667
+ # Mark a conversation read or unread and set its metadata. Requires a full-access live key; test keys
668
+ # get 403 test_key_restricted. Omitted fields are kept.
669
+ #
670
+ # @param id [String] Thread id
671
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
672
+ # @option params [Boolean] :read true sets read_at to now (unread again once a new email arrives); false
673
+ # clears it.
674
+ # @option params [Hash{String => String}] :metadata Your own key-value pairs (a ticket id, a CRM deal),
675
+ # replacing the previous ones. Limits: at most 20 keys matching [A-Za-z0-9_-]{1,40}, values up to 500
676
+ # bytes (UTF-8) (422 invalid_parameter).
677
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
678
+ # @return [ZapSMTP::Models::Thread]
679
+ def update(id, params = {}, request_options: {}, **kwargs)
680
+ @client.request(
681
+ method: :patch,
682
+ path: "/threads/#{Util.seg("id", id)}",
683
+ body: Util.params(params, kwargs),
684
+ model: Models::Thread,
685
+ request_options: request_options
686
+ )
687
+ end
688
+ end
689
+
690
+ # zap.inbound.domains
691
+ class InboundDomains
692
+ # @api private
693
+ def initialize(client)
694
+ @client = client
695
+ end
696
+
697
+ # List inbound domains.
698
+ #
699
+ # List inbound domains (oldest first). Requires a full-access key. MX target host comes from config
700
+ # (ZAP_INBOUND_HOST, defaults to the API hostname); managed zone from ZAP_INBOUND_ZONE.
701
+ #
702
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
703
+ # @return [ZapSMTP::Page<ZapSMTP::Models::InboundDomain>]
704
+ def list(request_options: {})
705
+ @client.request_page(
706
+ method: :get,
707
+ path: "/inbound/domains",
708
+ model: Models::InboundDomain,
709
+ paging: nil,
710
+ request_options: request_options
711
+ )
712
+ end
713
+
714
+ # Add an inbound domain.
715
+ #
716
+ # Create an inbound domain: a managed address (<slug>.<inbound zone>) or your own domain. Requires a
717
+ # full-access live key; test keys get 403 test_key_restricted.
718
+ #
719
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
720
+ # @option params [Boolean] :managed true: create an instant managed domain <10 random lowercase
721
+ # chars>.<inbound zone>; no DNS needed; name is ignored. Default: False.
722
+ # @option params [String] :name Required unless managed is true. Your own domain. It (or a parent) must
723
+ # be verified for sending by the account. Then publish MX 10 <inbound host> and call verify. Limits:
724
+ # invalid → 422 invalid_parameter "invalid domain name"; ZapSMTP-owned names → 422 reserved_domain; not
725
+ # verified for sending → 403 domain_not_verified
726
+ # @option params [Boolean] :reject_spam Refuse messages flagged as spam at SMTP time instead of
727
+ # delivering them with is_spam: true. Default: False.
728
+ # @option params [Boolean] :require_tls Accept encrypted mail only: senders without STARTTLS are refused
729
+ # with 530 5.7.0.
730
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
731
+ # @return [ZapSMTP::Models::InboundDomain]
732
+ def create(params = {}, request_options: {}, **kwargs)
733
+ @client.request(
734
+ method: :post,
735
+ path: "/inbound/domains",
736
+ body: Util.params(params, kwargs),
737
+ model: Models::InboundDomain,
738
+ request_options: request_options
739
+ )
740
+ end
741
+
742
+ # Retrieve an inbound domain.
743
+ #
744
+ # Retrieve an inbound domain. Requires a full-access key.
745
+ #
746
+ # @param id [String] Inbound domain id
747
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
748
+ # @return [ZapSMTP::Models::InboundDomain]
749
+ def get(id, request_options: {})
750
+ @client.request(
751
+ method: :get,
752
+ path: "/inbound/domains/#{Util.seg("id", id)}",
753
+ model: Models::InboundDomain,
754
+ request_options: request_options
755
+ )
756
+ end
757
+
758
+ # Update an inbound domain.
759
+ #
760
+ # Update an inbound domain's spam policy. Requires a full-access live key; test keys get 403
761
+ # test_key_restricted.
762
+ #
763
+ # @param id [String] Inbound domain id
764
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
765
+ # @option params [Boolean] :reject_spam Refuse flagged spam (550) instead of delivering it with is_spam:
766
+ # true.
767
+ # @option params [Boolean] :require_tls Accept encrypted mail only: senders without STARTTLS are refused
768
+ # with 530 5.7.0.
769
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
770
+ # @return [ZapSMTP::Models::InboundDomain]
771
+ def update(id, params = {}, request_options: {}, **kwargs)
772
+ @client.request(
773
+ method: :patch,
774
+ path: "/inbound/domains/#{Util.seg("id", id)}",
775
+ body: Util.params(params, kwargs),
776
+ model: Models::InboundDomain,
777
+ request_options: request_options
778
+ )
779
+ end
780
+
781
+ # Verify MX records.
782
+ #
783
+ # Check the domain's MX record now. Requires a full-access live key; test keys get 403
784
+ # test_key_restricted. mx_verified becomes true as soon as any MX record of the domain points to our
785
+ # inbound host.
786
+ #
787
+ # @param id [String] Inbound domain id
788
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
789
+ # @return [ZapSMTP::Models::InboundDomainCheck]
790
+ def verify(id, request_options: {})
791
+ @client.request(
792
+ method: :post,
793
+ path: "/inbound/domains/#{Util.seg("id", id)}/verify",
794
+ model: Models::InboundDomainCheck,
795
+ request_options: request_options
796
+ )
797
+ end
798
+
799
+ # Delete an inbound domain.
800
+ #
801
+ # Delete an inbound domain. Requires a full-access live key; test keys get 403 test_key_restricted.
802
+ #
803
+ # @param id [String] Inbound domain id
804
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
805
+ # @return [nil]
806
+ def delete(id, request_options: {})
807
+ @client.request(
808
+ method: :delete,
809
+ path: "/inbound/domains/#{Util.seg("id", id)}",
810
+ model: nil,
811
+ request_options: request_options
812
+ )
813
+ end
814
+ end
815
+
816
+ # zap.inbound.routes
817
+ class InboundRoutes
818
+ # @api private
819
+ def initialize(client)
820
+ @client = client
821
+ end
822
+
823
+ # List routes.
824
+ #
825
+ # List inbound routes in evaluation order (priority ascending, then created_at). Requires a full-access
826
+ # key.
827
+ #
828
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
829
+ # @return [ZapSMTP::Page<ZapSMTP::Models::InboundRoute>]
830
+ def list(request_options: {})
831
+ @client.request_page(
832
+ method: :get,
833
+ path: "/inbound/routes",
834
+ model: Models::InboundRoute,
835
+ paging: nil,
836
+ request_options: request_options
837
+ )
838
+ end
839
+
840
+ # Create a route.
841
+ #
842
+ # Create an inbound route (max 100 per account). Requires a full-access live key; test keys get 403
843
+ # test_key_restricted.
844
+ #
845
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
846
+ # @option params [String] :name Label (trimmed).
847
+ # @option params [Integer] :priority Lower runs first; first match wins. Default: 100.
848
+ # @option params [String] :match_recipient Glob (case-insensitive, * and ?) e.g. support+*@acme.com, or
849
+ # /regex/ (RE2, case-insensitive). Empty matches all. Limits: max 512 chars; must compile (422
850
+ # invalid_parameter)
851
+ # @option params [String] :match_sender Same syntax, matched against the envelope sender. Limits: max
852
+ # 512 chars; must compile
853
+ # @option params [String] :match_header Header name to test.
854
+ # @option params [String] :match_header_value Glob or /regex/ for that header's value. Limits: max 512
855
+ # chars; must compile
856
+ # @option params [String] :action webhook: deliver email.received only to webhook_id; store: keep
857
+ # without webhook; forward: keep and forward to forward_id (a confirmed forward destination); reject:
858
+ # refuse with 550 at SMTP time. Limits: 422 invalid_parameter "action must be webhook, store, reject or
859
+ # forward" Required. One of: webhook, store, forward, reject.
860
+ # @option params [String, nil] :webhook_id Required when action is webhook. A webhook of this account.
861
+ # Cleared for store/reject. Limits: 422 "webhook_id is required for action webhook" / "webhook_id does
862
+ # not belong to this account"
863
+ # @option params [String, nil] :forward_id A confirmed forward destination of this account (action
864
+ # forward). Cleared for other actions. Limits: 422 "forward_id is required for action forward" /
865
+ # "forward_id does not belong to this account" / "... is not confirmed yet"
866
+ # @option params [Boolean] :enabled Default: True.
867
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
868
+ # @return [ZapSMTP::Models::InboundRoute]
869
+ def create(params = {}, request_options: {}, **kwargs)
870
+ @client.request(
871
+ method: :post,
872
+ path: "/inbound/routes",
873
+ body: Util.params(params, kwargs),
874
+ model: Models::InboundRoute,
875
+ request_options: request_options
876
+ )
877
+ end
878
+
879
+ # Retrieve a route.
880
+ #
881
+ # Retrieve an inbound route. Requires a full-access key.
882
+ #
883
+ # @param id [String] Route id
884
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
885
+ # @return [ZapSMTP::Models::InboundRoute]
886
+ def get(id, request_options: {})
887
+ @client.request(
888
+ method: :get,
889
+ path: "/inbound/routes/#{Util.seg("id", id)}",
890
+ model: Models::InboundRoute,
891
+ request_options: request_options
892
+ )
893
+ end
894
+
895
+ # Update a route.
896
+ #
897
+ # Update an inbound route (partial; same fields and validation as create). Requires a full-access live
898
+ # key; test keys get 403 test_key_restricted. Any subset of the POST /inbound/routes fields. Omitted
899
+ # fields keep their value; webhook_id: "" clears it. The resulting route must still be valid (e.g.
900
+ # action webhook needs webhook_id).
901
+ #
902
+ # @param id [String] Route id
903
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
904
+ # @option params [String] :name Label (trimmed).
905
+ # @option params [Integer] :priority Lower runs first; first match wins.
906
+ # @option params [String] :match_recipient Glob (case-insensitive, * and ?) e.g. support+*@acme.com, or
907
+ # /regex/ (RE2, case-insensitive). Empty matches all. Limits: max 512 chars; must compile (422
908
+ # invalid_parameter)
909
+ # @option params [String] :match_sender Same syntax, matched against the envelope sender. Limits: max
910
+ # 512 chars; must compile
911
+ # @option params [String] :match_header Header name to test.
912
+ # @option params [String] :match_header_value Glob or /regex/ for that header's value. Limits: max 512
913
+ # chars; must compile
914
+ # @option params [String] :action webhook: deliver email.received only to webhook_id; store: keep
915
+ # without webhook; forward: keep and forward to forward_id (a confirmed forward destination); reject:
916
+ # refuse with 550 at SMTP time. Limits: 422 invalid_parameter "action must be webhook, store, reject or
917
+ # forward" One of: webhook, store, forward, reject.
918
+ # @option params [String, nil] :webhook_id A webhook of this account. Cleared for store/reject. Limits:
919
+ # 422 "webhook_id is required for action webhook" / "webhook_id does not belong to this account"
920
+ # @option params [String, nil] :forward_id A confirmed forward destination of this account (action
921
+ # forward). Cleared for other actions. Limits: 422 "forward_id is required for action forward" /
922
+ # "forward_id does not belong to this account" / "... is not confirmed yet"
923
+ # @option params [Boolean] :enabled
924
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
925
+ # @return [ZapSMTP::Models::InboundRoute]
926
+ def update(id, params = {}, request_options: {}, **kwargs)
927
+ @client.request(
928
+ method: :patch,
929
+ path: "/inbound/routes/#{Util.seg("id", id)}",
930
+ body: Util.params(params, kwargs),
931
+ model: Models::InboundRoute,
932
+ request_options: request_options
933
+ )
934
+ end
935
+
936
+ # Delete a route.
937
+ #
938
+ # Delete an inbound route. Requires a full-access live key; test keys get 403 test_key_restricted.
939
+ #
940
+ # @param id [String] Route id
941
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
942
+ # @return [nil]
943
+ def delete(id, request_options: {})
944
+ @client.request(
945
+ method: :delete,
946
+ path: "/inbound/routes/#{Util.seg("id", id)}",
947
+ model: nil,
948
+ request_options: request_options
949
+ )
950
+ end
951
+ end
952
+
953
+ # zap.inbound.forward_destinations
954
+ class InboundForwardDestinations
955
+ # @api private
956
+ def initialize(client)
957
+ @client = client
958
+ end
959
+
960
+ # List forward destinations.
961
+ #
962
+ # List the addresses received mail can be forwarded to. Requires a full-access key.
963
+ #
964
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
965
+ # @return [ZapSMTP::Page<ZapSMTP::Models::ForwardDestination>]
966
+ def list(request_options: {})
967
+ @client.request_page(
968
+ method: :get,
969
+ path: "/inbound/forward-destinations",
970
+ model: Models::ForwardDestination,
971
+ paging: nil,
972
+ request_options: request_options
973
+ )
974
+ end
975
+
976
+ # Add a forward destination.
977
+ #
978
+ # Add a forward destination: we email it a confirmation link; routes can forward there once its owner
979
+ # confirms. Requires a full-access live key; test keys get 403 test_key_restricted. The confirmation
980
+ # page asks for a click, so mail scanners that follow links cannot confirm. Forwarded mail keeps its
981
+ # original From and DKIM, is ARC-signed by us, counts as one sent email and appears in the email log;
982
+ # spam is never forwarded.
983
+ #
984
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
985
+ # @option params [String] :email A plain address. Not a ZapSMTP receiving address (it would loop).
986
+ # Required.
987
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
988
+ # @return [ZapSMTP::Models::ForwardDestination]
989
+ def create(params = {}, request_options: {}, **kwargs)
990
+ @client.request(
991
+ method: :post,
992
+ path: "/inbound/forward-destinations",
993
+ body: Util.params(params, kwargs),
994
+ model: Models::ForwardDestination,
995
+ request_options: request_options
996
+ )
997
+ end
998
+
999
+ # Resend the confirmation.
1000
+ #
1001
+ # Email a new confirmation link (the previous one stops working). Requires a full-access live key; test
1002
+ # keys get 403 test_key_restricted.
1003
+ #
1004
+ # @param id [String] Forward destination id.
1005
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1006
+ # @return [ZapSMTP::Models::ForwardDestination]
1007
+ def resend_confirmation(id, request_options: {})
1008
+ @client.request(
1009
+ method: :post,
1010
+ path: "/inbound/forward-destinations/#{Util.seg("id", id)}/resend",
1011
+ model: Models::ForwardDestination,
1012
+ request_options: request_options
1013
+ )
1014
+ end
1015
+
1016
+ # Remove a forward destination.
1017
+ #
1018
+ # Remove a forward destination; routes forwarding there only store from then on. Requires a full-access
1019
+ # live key; test keys get 403 test_key_restricted.
1020
+ #
1021
+ # @param id [String] Forward destination id.
1022
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1023
+ # @return [ZapSMTP::Models::Deleted]
1024
+ def delete(id, request_options: {})
1025
+ @client.request(
1026
+ method: :delete,
1027
+ path: "/inbound/forward-destinations/#{Util.seg("id", id)}",
1028
+ model: Models::Deleted,
1029
+ request_options: request_options
1030
+ )
1031
+ end
1032
+ end
1033
+
1034
+ # zap.inbound
1035
+ class Inbound
1036
+ # @return [InboundDomains]
1037
+ attr_reader :domains
1038
+
1039
+ # @return [InboundRoutes]
1040
+ attr_reader :routes
1041
+
1042
+ # @return [InboundForwardDestinations]
1043
+ attr_reader :forward_destinations
1044
+
1045
+ # @api private
1046
+ def initialize(client)
1047
+ @client = client
1048
+ @domains = InboundDomains.new(client)
1049
+ @routes = InboundRoutes.new(client)
1050
+ @forward_destinations = InboundForwardDestinations.new(client)
1051
+ end
1052
+
1053
+ # Inbound stats.
1054
+ #
1055
+ # Inbound counters for the last 24 hours. Requires a full-access key.
1056
+ #
1057
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1058
+ # @return [ZapSMTP::Models::InboundStats]
1059
+ def get_stats(request_options: {})
1060
+ @client.request(
1061
+ method: :get,
1062
+ path: "/inbound/stats",
1063
+ model: Models::InboundStats,
1064
+ request_options: request_options
1065
+ )
1066
+ end
1067
+ end
1068
+
1069
+ # zap.simulator
1070
+ class Simulator
1071
+ # @api private
1072
+ def initialize(client)
1073
+ @client = client
1074
+ end
1075
+
1076
+ # List simulator addresses.
1077
+ #
1078
+ # List the simulator addresses and the events each produces. Requires a full-access key.
1079
+ #
1080
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1081
+ # @return [ZapSMTP::Models::Simulator]
1082
+ def get(request_options: {})
1083
+ @client.request(
1084
+ method: :get,
1085
+ path: "/simulator",
1086
+ model: Models::Simulator,
1087
+ request_options: request_options
1088
+ )
1089
+ end
1090
+ end
1091
+
1092
+ # zap.stats
1093
+ class Stats
1094
+ # @api private
1095
+ def initialize(client)
1096
+ @client = client
1097
+ end
1098
+
1099
+ # Totals.
1100
+ #
1101
+ # Event counts by status over the last N hours (live traffic only). Requires a full-access key. Counts
1102
+ # events (not unique emails), ordered by status name; test-mode traffic excluded.
1103
+ #
1104
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
1105
+ # @option params [Integer] :hours 1-720; out-of-range falls back to 24. Default: 24.
1106
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1107
+ # @return [ZapSMTP::Models::Stats]
1108
+ def get(params = {}, request_options: {}, **kwargs)
1109
+ @client.request(
1110
+ method: :get,
1111
+ path: "/stats",
1112
+ query: Util.params(params, kwargs),
1113
+ model: Models::Stats,
1114
+ request_options: request_options
1115
+ )
1116
+ end
1117
+
1118
+ # Time series.
1119
+ #
1120
+ # Event counts by status in time buckets. Requires a full-access key. One point per (bucket, status);
1121
+ # empty buckets are not emitted. Test-mode traffic excluded.
1122
+ #
1123
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
1124
+ # @option params [Integer] :hours 1-720; out-of-range falls back to 24. Bucket size: <=1h → 60 s, <=6h →
1125
+ # 300 s, <=24h → 1800 s, <=168h → 10800 s, otherwise 43200 s. Default: 24.
1126
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1127
+ # @return [ZapSMTP::Models::StatsTimeseries]
1128
+ def timeseries(params = {}, request_options: {}, **kwargs)
1129
+ @client.request(
1130
+ method: :get,
1131
+ path: "/stats/timeseries",
1132
+ query: Util.params(params, kwargs),
1133
+ model: Models::StatsTimeseries,
1134
+ request_options: request_options
1135
+ )
1136
+ end
1137
+
1138
+ # Breakdown.
1139
+ #
1140
+ # Per-provider delivery, bounce classes, engagement and top clicked links. Requires a full-access key.
1141
+ # Providers are Gmail, Microsoft, Yahoo, Apple and Other. delayed counts emails that were delayed at
1142
+ # least once.
1143
+ #
1144
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
1145
+ # @option params [Integer] :hours 1-720; out-of-range falls back to 24. Default: 24.
1146
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1147
+ # @return [ZapSMTP::Models::StatsBreakdown]
1148
+ def breakdown(params = {}, request_options: {}, **kwargs)
1149
+ @client.request(
1150
+ method: :get,
1151
+ path: "/stats/breakdown",
1152
+ query: Util.params(params, kwargs),
1153
+ model: Models::StatsBreakdown,
1154
+ request_options: request_options
1155
+ )
1156
+ end
1157
+
1158
+ # Metrics by domain, stream, tag or provider.
1159
+ #
1160
+ # Delivery and engagement of live mail by sending domain, stream, tag or mailbox provider, with rates
1161
+ # and a time series. Requires a full-access key. Counts are recipients, except delayed, opened and
1162
+ # clicked: unique emails. Delivery and bounce rates are of sent; complaint, open and click rates of
1163
+ # delivered. Test-mode mail is excluded. Kept for 400 days. An out-of-band bounce (a later bounce email
1164
+ # from the remote server) has no sending domain: it is grouped under an empty value. Totals and the
1165
+ # series count each email once whatever the dimension; with dimension=tag an email with several tags
1166
+ # appears in each of its tags' groups.
1167
+ #
1168
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
1169
+ # @option params [String] :from RFC 3339 start. At most 400 days before to. Default: 7 days ago.
1170
+ # @option params [String] :to RFC 3339 end (exclusive). Default: now.
1171
+ # @option params [String] :granularity hour (ranges up to 31 days) or day for series. Default: hour up
1172
+ # to 48 hours, else day.
1173
+ # @option params [String] :dimension domain, stream, tag or provider: adds groups, one row per value,
1174
+ # busiest first.
1175
+ # @option params [String] :domain Only this sending (From) domain.
1176
+ # @option params [String] :stream transactional or broadcast.
1177
+ # @option params [String] :provider Gmail, Microsoft, Yahoo, Apple or Other.
1178
+ # @option params [String] :tag Only emails with this tag, as name=value. Cannot be combined with domain,
1179
+ # stream or provider, and groups only by tag.
1180
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1181
+ # @return [ZapSMTP::Models::Metrics]
1182
+ def metrics(params = {}, request_options: {}, **kwargs)
1183
+ @client.request(
1184
+ method: :get,
1185
+ path: "/metrics",
1186
+ query: Util.params(params, kwargs),
1187
+ model: Models::Metrics,
1188
+ request_options: request_options
1189
+ )
1190
+ end
1191
+ end
1192
+
1193
+ # zap.domains
1194
+ class Domains
1195
+ # @api private
1196
+ def initialize(client)
1197
+ @client = client
1198
+ end
1199
+
1200
+ # List domains.
1201
+ #
1202
+ # List sending domains (newest first) with their DNS records. Requires a full-access key. status is
1203
+ # pending or verified. Only DKIM is required to verify a domain; SPF and DMARC are recommended and
1204
+ # reported separately.
1205
+ #
1206
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1207
+ # @return [ZapSMTP::Page<ZapSMTP::Models::Domain>]
1208
+ def list(request_options: {})
1209
+ @client.request_page(
1210
+ method: :get,
1211
+ path: "/domains",
1212
+ model: Models::Domain,
1213
+ paging: nil,
1214
+ request_options: request_options
1215
+ )
1216
+ end
1217
+
1218
+ # Add a domain.
1219
+ #
1220
+ # Add a sending domain; returns the DNS records to publish. Requires a full-access live key; test keys
1221
+ # get 403 test_key_restricted.
1222
+ #
1223
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
1224
+ # @option params [String] :name Domain name (lowercased, trailing dot removed). Limits: valid hostname
1225
+ # <=253 chars, else 422 invalid_parameter "invalid domain name" Required.
1226
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1227
+ # @return [ZapSMTP::Models::Domain]
1228
+ def create(params = {}, request_options: {}, **kwargs)
1229
+ @client.request(
1230
+ method: :post,
1231
+ path: "/domains",
1232
+ body: Util.params(params, kwargs),
1233
+ model: Models::Domain,
1234
+ request_options: request_options
1235
+ )
1236
+ end
1237
+
1238
+ # Retrieve a domain.
1239
+ #
1240
+ # Retrieve a sending domain. Requires a full-access key.
1241
+ #
1242
+ # @param id [String] Domain id
1243
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1244
+ # @return [ZapSMTP::Models::Domain]
1245
+ def get(id, request_options: {})
1246
+ @client.request(
1247
+ method: :get,
1248
+ path: "/domains/#{Util.seg("id", id)}",
1249
+ model: Models::Domain,
1250
+ request_options: request_options
1251
+ )
1252
+ end
1253
+
1254
+ # Update a domain.
1255
+ #
1256
+ # Set the domain's tracking defaults (opens, clicks, replies) and its outbound TLS policy. Requires a
1257
+ # full-access live key; test keys get 403 test_key_restricted. Fields left out keep their value. The
1258
+ # response is the domain, as in GET /domains/{id}. Reply tracking: each tracked email gets its own
1259
+ # signed Reply-To, e.g. r1-<email id>.<signature>@reply.acme.com, so replies come back tied to the exact
1260
+ # email. Each reply fires email.replied (classified as a person, out-of-office, unsubscribe request,
1261
+ # bounce…) and arrives as a received email; only replies a person wrote are forwarded. The display name
1262
+ # is kept (the Reply-To’s name, else the From name). One reply address takes at most 100 replies a day.
1263
+ #
1264
+ # @param id [String] Domain id
1265
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
1266
+ # @option params [Boolean] :open_tracking Default open tracking for emails from this domain.
1267
+ # @option params [Boolean] :click_tracking Default click tracking for emails from this domain.
1268
+ # @option params [String] :tls Outbound encryption: opportunistic (default: encrypt whenever offered),
1269
+ # required (TLS or no delivery) or verified (TLS with a valid certificate). Limits: other values → 422
1270
+ # invalid_parameter "tls must be opportunistic, required or verified"
1271
+ # @option params [Boolean] :reply_tracking Default reply tracking for emails from this domain (override
1272
+ # per email with tracking.replies). Limits: true without a reply_domain → 422 invalid_parameter
1273
+ # "reply_tracking needs a reply_domain: add an inbound domain such as reply.<domain> first"
1274
+ # @option params [String] :reply_domain Where tracked reply addresses live: one of your inbound domains,
1275
+ # MX-verified, equal to this domain or a subdomain of it (e.g. reply.acme.com). "" clears it. Limits:
1276
+ # otherwise 422 invalid_parameter
1277
+ # @option params [String] :reply_forward_to Where replies a person wrote are forwarded: a plain address
1278
+ # on one of your verified domains, or a confirmed forward destination; never a receiving address. ""
1279
+ # (default) forwards to the email’s first Reply-To, else its From. Limits: otherwise 422
1280
+ # invalid_parameter
1281
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1282
+ # @return [ZapSMTP::Models::Domain]
1283
+ def update(id, params = {}, request_options: {}, **kwargs)
1284
+ @client.request(
1285
+ method: :patch,
1286
+ path: "/domains/#{Util.seg("id", id)}",
1287
+ body: Util.params(params, kwargs),
1288
+ model: Models::Domain,
1289
+ request_options: request_options
1290
+ )
1291
+ end
1292
+
1293
+ # Verify a domain.
1294
+ #
1295
+ # Check DKIM/SPF/DMARC DNS now and update the domain's status. Requires a full-access live key; test
1296
+ # keys get 403 test_key_restricted. found shows, per DNS name, what is published right now. For the root
1297
+ # domain only SPF-type TXT values are listed; a DMARC policy inherited from the parent domain is marked
1298
+ # “(inherited from _dmarc.<domain>)”.
1299
+ #
1300
+ # @param id [String] Domain id
1301
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1302
+ # @return [ZapSMTP::Models::Domain]
1303
+ def verify(id, request_options: {})
1304
+ @client.request(
1305
+ method: :post,
1306
+ path: "/domains/#{Util.seg("id", id)}/verify",
1307
+ model: Models::Domain,
1308
+ request_options: request_options
1309
+ )
1310
+ end
1311
+
1312
+ # Delete a domain.
1313
+ #
1314
+ # Delete a sending domain. Requires a full-access live key; test keys get 403 test_key_restricted.
1315
+ #
1316
+ # @param id [String] Domain id
1317
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1318
+ # @return [nil]
1319
+ def delete(id, request_options: {})
1320
+ @client.request(
1321
+ method: :delete,
1322
+ path: "/domains/#{Util.seg("id", id)}",
1323
+ model: nil,
1324
+ request_options: request_options
1325
+ )
1326
+ end
1327
+
1328
+ # DMARC reports.
1329
+ #
1330
+ # DMARC aggregate reports about the domain: the address to publish in your DMARC record and what mailbox
1331
+ # providers reported. Requires a full-access key. Add rua to your DMARC record (keep your policy).
1332
+ # Providers send one report a day; reports are kept 400 days. ours marks ZapSMTP sending IPs: another IP
1333
+ # that fails DMARC is a service you have not set up (add its DKIM/SPF) or someone spoofing your domain.
1334
+ #
1335
+ # @param id [String] Domain id.
1336
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
1337
+ # @option params [Integer] :days 1-180; out-of-range falls back to 30. Default: 30.
1338
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1339
+ # @return [ZapSMTP::Models::DmarcSummary]
1340
+ def get_dmarc(id, params = {}, request_options: {}, **kwargs)
1341
+ @client.request(
1342
+ method: :get,
1343
+ path: "/domains/#{Util.seg("id", id)}/dmarc",
1344
+ query: Util.params(params, kwargs),
1345
+ model: Models::DmarcSummary,
1346
+ request_options: request_options
1347
+ )
1348
+ end
1349
+
1350
+ # Domain reputation.
1351
+ #
1352
+ # Blocklist (DNSBL) status of a sending domain. Requires a full-access key. Customer domains are checked
1353
+ # automatically every 6 hours (operator-configurable). The exact JSON for codes/labels when empty (null
1354
+ # vs []) depends on the stored arrays; not verified.
1355
+ #
1356
+ # @param id [String] Domain id
1357
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1358
+ # @return [ZapSMTP::Models::DomainReputation]
1359
+ def get_reputation(id, request_options: {})
1360
+ @client.request(
1361
+ method: :get,
1362
+ path: "/domains/#{Util.seg("id", id)}/reputation",
1363
+ model: Models::DomainReputation,
1364
+ request_options: request_options
1365
+ )
1366
+ end
1367
+
1368
+ # Check reputation now.
1369
+ #
1370
+ # Run a blocklist check of the domain now and return its reputation. Requires a full-access live key;
1371
+ # test keys get 403 test_key_restricted. At most once per minute per domain name. No Retry-After header
1372
+ # is set.
1373
+ #
1374
+ # @param id [String] Domain id
1375
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1376
+ # @return [ZapSMTP::Models::DomainReputation]
1377
+ def check_reputation(id, request_options: {})
1378
+ @client.request(
1379
+ method: :post,
1380
+ path: "/domains/#{Util.seg("id", id)}/reputation/check",
1381
+ model: Models::DomainReputation,
1382
+ request_options: request_options
1383
+ )
1384
+ end
1385
+
1386
+ # Retrieve brand settings.
1387
+ #
1388
+ # Brand-in-the-inbox status: sender name, BIMI logo/certificate, DMARC enforcement and per-provider
1389
+ # readiness. Requires a full-access key.
1390
+ #
1391
+ # @param id [String] Domain id
1392
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1393
+ # @return [ZapSMTP::Models::Brand]
1394
+ def get_brand(id, request_options: {})
1395
+ @client.request(
1396
+ method: :get,
1397
+ path: "/domains/#{Util.seg("id", id)}/brand",
1398
+ model: Models::Brand,
1399
+ request_options: request_options
1400
+ )
1401
+ end
1402
+
1403
+ # Update brand settings.
1404
+ #
1405
+ # Set the default sender name and upload/remove the BIMI logo and certificate. Requires a full-access
1406
+ # live key; test keys get 403 test_key_restricted. Hosted files are served publicly at
1407
+ # /bimi/<domain>/logo.svg and /bimi/<domain>/cert.pem (outside /v1) for verified domains only.
1408
+ #
1409
+ # @param id [String] Domain id
1410
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
1411
+ # @option params [String] :from_name Display name used when an email's from has only an address. ""
1412
+ # clears it. Limits: max 70 characters, no < > " or line breaks → 422 invalid_parameter
1413
+ # @option params [String] :logo_svg SVG source; normalized to SVG Tiny PS (fixes reported in logo_fixed,
1414
+ # warnings in logo_warnings). Limits: max 32 KB and valid SVG → otherwise 422 invalid_logo
1415
+ # @option params [String] :cert_pem VMC/CMC PEM chain (certificate, intermediate, root). Limits: 422
1416
+ # invalid_certificate
1417
+ # @option params [Boolean] :remove_logo Default: False.
1418
+ # @option params [Boolean] :remove_cert Default: False.
1419
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1420
+ # @return [ZapSMTP::Models::Brand]
1421
+ def update_brand(id, params = {}, request_options: {}, **kwargs)
1422
+ @client.request(
1423
+ method: :put,
1424
+ path: "/domains/#{Util.seg("id", id)}/brand",
1425
+ body: Util.params(params, kwargs),
1426
+ model: Models::Brand,
1427
+ request_options: request_options
1428
+ )
1429
+ end
1430
+ end
1431
+
1432
+ # zap.api_keys
1433
+ class ApiKeys
1434
+ # @api private
1435
+ def initialize(client)
1436
+ @client = client
1437
+ end
1438
+
1439
+ # List API keys.
1440
+ #
1441
+ # List active API keys (newest first); tokens are never returned. Requires a full-access key. Revoked
1442
+ # keys and SMTP credentials are not listed. last_used_at is updated at most every 5 minutes.
1443
+ #
1444
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1445
+ # @return [ZapSMTP::Page<ZapSMTP::Models::ApiKey>]
1446
+ def list(request_options: {})
1447
+ @client.request_page(
1448
+ method: :get,
1449
+ path: "/api-keys",
1450
+ model: Models::ApiKey,
1451
+ paging: nil,
1452
+ request_options: request_options
1453
+ )
1454
+ end
1455
+
1456
+ # Create an API key.
1457
+ #
1458
+ # Create an API key; the full key (token) is returned only once. Requires a full-access live key; test
1459
+ # keys get 403 test_key_restricted.
1460
+ #
1461
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
1462
+ # @option params [String] :name Limits: 1-100 characters (not trimmed) → 422 invalid_parameter "name is
1463
+ # required (max 100 chars)" Required.
1464
+ # @option params [String] :permission One of: full_access, sending_access. Default: full_access.
1465
+ # @option params [String] :domain_id Restrict sending to one of the account's domains. Only with
1466
+ # sending_access. Limits: 422 "domain_id can only be used with sending_access" / "unknown domain_id"
1467
+ # @option params [String] :mode test creates a zap_test_ key (see API keys). One of: live, test.
1468
+ # Default: live.
1469
+ # @option params [String] :stream Restrict the key to one message stream. One of: transactional,
1470
+ # broadcast.
1471
+ # @option params [String] :expires_at Limits: must be in the future → 422 "expires_at must be in the
1472
+ # future"
1473
+ # @option params [Integer] :expires_in_days Alternative to expires_at; when > 0 it overrides expires_at.
1474
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1475
+ # @return [ZapSMTP::Models::CreatedApiKey]
1476
+ def create(params = {}, request_options: {}, **kwargs)
1477
+ @client.request(
1478
+ method: :post,
1479
+ path: "/api-keys",
1480
+ body: Util.params(params, kwargs),
1481
+ model: Models::CreatedApiKey,
1482
+ request_options: request_options
1483
+ )
1484
+ end
1485
+
1486
+ # Revoke an API key.
1487
+ #
1488
+ # Revoke an API key immediately. Requires a full-access live key; test keys get 403 test_key_restricted.
1489
+ #
1490
+ # @param id [String] API key id
1491
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1492
+ # @return [nil]
1493
+ def delete(id, request_options: {})
1494
+ @client.request(
1495
+ method: :delete,
1496
+ path: "/api-keys/#{Util.seg("id", id)}",
1497
+ model: nil,
1498
+ request_options: request_options
1499
+ )
1500
+ end
1501
+
1502
+ # Update an API key.
1503
+ #
1504
+ # Rename a key or change its permission and restrictions. The token and the mode never change; the new
1505
+ # rights apply to the next request. Requires a full-access live key; test keys get 403
1506
+ # test_key_restricted.
1507
+ #
1508
+ # @param id [String] API key id.
1509
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
1510
+ # @option params [String] :name 1–100 characters.
1511
+ # @option params [String] :permission One of: full_access, sending_access.
1512
+ # @option params [String, nil] :domain_id Restrict sending to one verified domain (sending access only).
1513
+ # null lifts the restriction.
1514
+ # @option params [String, nil] :stream Restrict to one stream. null lifts the restriction. One of:
1515
+ # transactional, broadcast.
1516
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1517
+ # @return [ZapSMTP::Models::ApiKey]
1518
+ def update(id, params = {}, request_options: {}, **kwargs)
1519
+ @client.request(
1520
+ method: :patch,
1521
+ path: "/api-keys/#{Util.seg("id", id)}",
1522
+ body: Util.params(params, kwargs),
1523
+ model: Models::ApiKey,
1524
+ request_options: request_options
1525
+ )
1526
+ end
1527
+ end
1528
+
1529
+ # zap.smtp_credentials
1530
+ class SmtpCredentials
1531
+ # @api private
1532
+ def initialize(client)
1533
+ @client = client
1534
+ end
1535
+
1536
+ # List SMTP credentials.
1537
+ #
1538
+ # List active SMTP credentials plus the plan limit and relay settings. Requires a full-access key. No
1539
+ # has_more field on this list. limit = plan's max SMTP credentials (0 = unlimited). smtp_relay is false
1540
+ # on the Free plan, which sends through the Email API only.
1541
+ #
1542
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1543
+ # @return [ZapSMTP::Models::SmtpCredentialList]
1544
+ def list(request_options: {})
1545
+ @client.request(
1546
+ method: :get,
1547
+ path: "/smtp-credentials",
1548
+ model: Models::SmtpCredentialList,
1549
+ request_options: request_options
1550
+ )
1551
+ end
1552
+
1553
+ # Create SMTP credentials.
1554
+ #
1555
+ # Create an SMTP credential; the password is returned only once. Requires a full-access live key; test
1556
+ # keys get 403 test_key_restricted. Password: 40 base62 characters. Credentials are sending-only (always
1557
+ # behave like sending_access, live mode) and cannot call the HTTP API.
1558
+ #
1559
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
1560
+ # @option params [String] :name Limits: trimmed, 1-100 characters → 422 invalid_parameter "name is
1561
+ # required (max 100 chars)" Required.
1562
+ # @option params [String] :domain_id Restrict the credential to one of the account's domains. Limits:
1563
+ # 422 invalid_parameter "unknown domain_id"
1564
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1565
+ # @return [ZapSMTP::Models::SmtpCredential]
1566
+ def create(params = {}, request_options: {}, **kwargs)
1567
+ @client.request(
1568
+ method: :post,
1569
+ path: "/smtp-credentials",
1570
+ body: Util.params(params, kwargs),
1571
+ model: Models::SmtpCredential,
1572
+ request_options: request_options
1573
+ )
1574
+ end
1575
+
1576
+ # Revoke SMTP credentials.
1577
+ #
1578
+ # Revoke an SMTP credential. Requires a full-access live key; test keys get 403 test_key_restricted.
1579
+ #
1580
+ # @param id [String] SMTP credential id
1581
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1582
+ # @return [nil]
1583
+ def delete(id, request_options: {})
1584
+ @client.request(
1585
+ method: :delete,
1586
+ path: "/smtp-credentials/#{Util.seg("id", id)}",
1587
+ model: nil,
1588
+ request_options: request_options
1589
+ )
1590
+ end
1591
+ end
1592
+
1593
+ # zap.webhooks.events
1594
+ class WebhooksEvents
1595
+ # @api private
1596
+ def initialize(client)
1597
+ @client = client
1598
+ end
1599
+
1600
+ # Replay an event.
1601
+ #
1602
+ # Re-send a past event (from the last 100 deliveries) to the endpoint now. Requires a full-access live
1603
+ # key; test keys get 403 test_key_restricted. Same body and Zap-Event-Id as the original, signed with
1604
+ # the current secret(s) and a new timestamp. The replay is sent synchronously and not retried. Events
1605
+ # whose body was over 64 KB cannot be replayed.
1606
+ #
1607
+ # @param id [String] Webhook id
1608
+ # @param event [String] Event id (evt_...) from GET /webhooks/{id}/deliveries
1609
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1610
+ # @return [ZapSMTP::Models::WebhookTestResult]
1611
+ def replay(id, event, request_options: {})
1612
+ @client.request(
1613
+ method: :post,
1614
+ path: "/webhooks/#{Util.seg("id", id)}/deliveries/#{Util.seg("event", event)}/replay",
1615
+ model: Models::WebhookTestResult,
1616
+ request_options: request_options
1617
+ )
1618
+ end
1619
+
1620
+ # List events.
1621
+ #
1622
+ # Events sent to this endpoint, newest first, each with its outcome and number of attempts (from the
1623
+ # endpoint’s last 100 delivery attempts). Requires a full-access key.
1624
+ #
1625
+ # @param id [String] Webhook id.
1626
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1627
+ # @return [ZapSMTP::Page<ZapSMTP::Models::WebhookEventRecord>]
1628
+ def list(id, request_options: {})
1629
+ @client.request_page(
1630
+ method: :get,
1631
+ path: "/webhooks/#{Util.seg("id", id)}/events",
1632
+ model: Models::WebhookEventRecord,
1633
+ paging: nil,
1634
+ request_options: request_options
1635
+ )
1636
+ end
1637
+
1638
+ # Retrieve an event.
1639
+ #
1640
+ # One event with its payload and every delivery attempt, oldest first. Requires a full-access key.
1641
+ #
1642
+ # @param id [String] Webhook id.
1643
+ # @param event [String] Event id (Zap-Event-Id).
1644
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1645
+ # @return [ZapSMTP::Models::WebhookEventRecord]
1646
+ def get(id, event, request_options: {})
1647
+ @client.request(
1648
+ method: :get,
1649
+ path: "/webhooks/#{Util.seg("id", id)}/events/#{Util.seg("event", event)}",
1650
+ model: Models::WebhookEventRecord,
1651
+ request_options: request_options
1652
+ )
1653
+ end
1654
+ end
1655
+
1656
+ # zap.webhooks
1657
+ class Webhooks
1658
+ # @return [WebhooksEvents]
1659
+ attr_reader :events
1660
+
1661
+ # @api private
1662
+ def initialize(client)
1663
+ @client = client
1664
+ @events = WebhooksEvents.new(client)
1665
+ end
1666
+
1667
+ # List webhooks.
1668
+ #
1669
+ # List webhook endpoints (newest first); secrets are omitted. Requires a full-access key.
1670
+ # previous_secret_expires_at appears while a rotated secret still signs deliveries.
1671
+ #
1672
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1673
+ # @return [ZapSMTP::Page<ZapSMTP::Models::Webhook>]
1674
+ def list(request_options: {})
1675
+ @client.request_page(
1676
+ method: :get,
1677
+ path: "/webhooks",
1678
+ model: Models::Webhook,
1679
+ paging: nil,
1680
+ request_options: request_options
1681
+ )
1682
+ end
1683
+
1684
+ # Create a webhook.
1685
+ #
1686
+ # Create a webhook endpoint; the signing secret is returned. Requires a full-access live key; test keys
1687
+ # get 403 test_key_restricted. The secret is also readable later via GET /webhooks/{id}. To send clicks
1688
+ # of one button to this endpoint: {"events": ["email.clicked"], "filter": {"actions":
1689
+ # ["confirm_order"]}}. Endpoints always return filter, with an empty list when there is none.
1690
+ #
1691
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
1692
+ # @option params [String] :url Absolute https:// URL. Limits: 422 invalid_parameter "url must be an
1693
+ # absolute https:// URL" Required.
1694
+ # @option params [Array<String>] :events Limits: unknown type → 422 invalid_parameter "unknown event
1695
+ # type <x>; allowed: ..." One of: email.sent, email.delivered, email.delivery_delayed, email.bounced,
1696
+ # email.complained, email.failed, email.opened, email.clicked, email.suppressed, email.received,
1697
+ # thread.created, thread.replied, email.replied. Default: all event types.
1698
+ # @option params [Boolean] :include_content email.received carries the message: text, html, headers, and
1699
+ # download links (valid 24 hours) for the attachments and the raw .eml; text and html are cut at 1 MB in
1700
+ # total (truncated: true). Default: false.
1701
+ # @option params [Boolean] :batch Send events up to 100 per request (or every second) as a JSON array,
1702
+ # signed as one body; Zap-Event-Id is the batch id, each event keeps its own id. email.received with the
1703
+ # full message still arrives alone. Default: false.
1704
+ # @option params [Hash] :filter Narrows email.clicked to some click actions; other event types are not
1705
+ # affected. Empty or absent: every click. Default: {"actions": []}.
1706
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1707
+ # @return [ZapSMTP::Models::Webhook]
1708
+ def create(params = {}, request_options: {}, **kwargs)
1709
+ @client.request(
1710
+ method: :post,
1711
+ path: "/webhooks",
1712
+ body: Util.params(params, kwargs),
1713
+ model: Models::Webhook,
1714
+ request_options: request_options
1715
+ )
1716
+ end
1717
+
1718
+ # Retrieve a webhook.
1719
+ #
1720
+ # Retrieve a webhook endpoint including its signing secret. Requires a full-access key.
1721
+ #
1722
+ # @param id [String] Webhook id
1723
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1724
+ # @return [ZapSMTP::Models::Webhook]
1725
+ def get(id, request_options: {})
1726
+ @client.request(
1727
+ method: :get,
1728
+ path: "/webhooks/#{Util.seg("id", id)}",
1729
+ model: Models::Webhook,
1730
+ request_options: request_options
1731
+ )
1732
+ end
1733
+
1734
+ # Update a webhook.
1735
+ #
1736
+ # Update a webhook's URL, events, click-action filter or enabled state. Requires a full-access live key;
1737
+ # test keys get 403 test_key_restricted. The response's disabled_reason reflects the value before the
1738
+ # update (the store clears it on re-enable but the returned object is not reloaded).
1739
+ #
1740
+ # @param id [String] Webhook id
1741
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
1742
+ # @option params [String] :url Limits: absolute https:// URL
1743
+ # @option params [Array<String>] :events Limits: [] → 422 "select at least one event"; unknown type →
1744
+ # 422 "unknown event type <x>" One of: email.sent, email.delivered, email.delivery_delayed,
1745
+ # email.bounced, email.complained, email.failed, email.opened, email.clicked, email.suppressed,
1746
+ # email.received, thread.created, thread.replied, email.replied.
1747
+ # @option params [Boolean] :enabled Re-enabling clears disabled_reason. Disabling drops pending
1748
+ # deliveries.
1749
+ # @option params [Boolean] :include_content email.received carries the message: text, html, headers, and
1750
+ # download links (valid 24 hours) for the attachments and the raw .eml; text and html are cut at 1 MB in
1751
+ # total (truncated: true). Default: false.
1752
+ # @option params [Boolean] :batch Send events up to 100 per request (or every second) as a JSON array,
1753
+ # signed as one body; Zap-Event-Id is the batch id, each event keeps its own id. email.received with the
1754
+ # full message still arrives alone. Default: false.
1755
+ # @option params [Hash] :filter Narrows email.clicked to some click actions; other event types are not
1756
+ # affected. Empty or absent: every click. Replaces the whole filter; {"actions": []} removes it.
1757
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1758
+ # @return [ZapSMTP::Models::Webhook]
1759
+ def update(id, params = {}, request_options: {}, **kwargs)
1760
+ @client.request(
1761
+ method: :patch,
1762
+ path: "/webhooks/#{Util.seg("id", id)}",
1763
+ body: Util.params(params, kwargs),
1764
+ model: Models::Webhook,
1765
+ request_options: request_options
1766
+ )
1767
+ end
1768
+
1769
+ # Delete a webhook.
1770
+ #
1771
+ # Delete a webhook endpoint. Requires a full-access live key; test keys get 403 test_key_restricted.
1772
+ #
1773
+ # @param id [String] Webhook id
1774
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1775
+ # @return [nil]
1776
+ def delete(id, request_options: {})
1777
+ @client.request(
1778
+ method: :delete,
1779
+ path: "/webhooks/#{Util.seg("id", id)}",
1780
+ model: nil,
1781
+ request_options: request_options
1782
+ )
1783
+ end
1784
+
1785
+ # Send a test event.
1786
+ #
1787
+ # Send a signed sample event to the endpoint now and report the result. Requires a full-access live key;
1788
+ # test keys get 403 test_key_restricted. Test events are not retried. delivery.error is present when the
1789
+ # attempt failed (e.g. "HTTP 500"); status_code is 0 on network errors. The test attempt is recorded in
1790
+ # the delivery log.
1791
+ #
1792
+ # @param id [String] Webhook id
1793
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
1794
+ # @option params [String] :type Limits: 422 invalid_parameter "unknown event type" One of: email.sent,
1795
+ # email.delivered, email.delivery_delayed, email.bounced, email.complained, email.failed, email.opened,
1796
+ # email.clicked, email.suppressed, email.received, thread.created, thread.replied, email.replied.
1797
+ # Default: email.delivered.
1798
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1799
+ # @return [ZapSMTP::Models::WebhookTestResult]
1800
+ def test(id, params = {}, request_options: {}, **kwargs)
1801
+ @client.request(
1802
+ method: :post,
1803
+ path: "/webhooks/#{Util.seg("id", id)}/test",
1804
+ body: Util.params(params, kwargs),
1805
+ model: Models::WebhookTestResult,
1806
+ request_options: request_options
1807
+ )
1808
+ end
1809
+
1810
+ # List delivery attempts.
1811
+ #
1812
+ # List the last 100 delivery attempts of a webhook (newest first). Requires a full-access key. attempt
1813
+ # starts at 1. body is the exact payload sent (omitted above 64 KB); error is omitted on success.
1814
+ #
1815
+ # @param id [String] Webhook id
1816
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1817
+ # @return [ZapSMTP::Page<ZapSMTP::Models::WebhookDelivery>]
1818
+ def list_deliveries(id, request_options: {})
1819
+ @client.request_page(
1820
+ method: :get,
1821
+ path: "/webhooks/#{Util.seg("id", id)}/deliveries",
1822
+ model: Models::WebhookDelivery,
1823
+ paging: nil,
1824
+ request_options: request_options
1825
+ )
1826
+ end
1827
+
1828
+ # Rotate the signing secret.
1829
+ #
1830
+ # Generate a new signing secret; the old one stays valid for 24 hours. Requires a full-access live key;
1831
+ # test keys get 403 test_key_restricted. During the grace period Zap-Signature carries two v1= entries
1832
+ # (new secret first). Rotating again replaces the previous secret.
1833
+ #
1834
+ # @param id [String] Webhook id
1835
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1836
+ # @return [ZapSMTP::Models::Webhook]
1837
+ def rotate_secret(id, request_options: {})
1838
+ @client.request(
1839
+ method: :post,
1840
+ path: "/webhooks/#{Util.seg("id", id)}/rotate-secret",
1841
+ model: Models::Webhook,
1842
+ request_options: request_options
1843
+ )
1844
+ end
1845
+
1846
+ # Checks a webhook request's Zap-Signature and returns its event (see ZapSMTP::Webhook.verify).
1847
+ #
1848
+ # @return [ZapSMTP::WebhookEvent]
1849
+ def verify(payload, headers, secret, **options)
1850
+ ZapSMTP::Webhook.verify(payload, headers, secret, **options)
1851
+ end
1852
+
1853
+ # Checks a webhook request's Zap-Signature and returns its events: every event of a batch, or the one
1854
+ # event (see ZapSMTP::Webhook.verify_events).
1855
+ #
1856
+ # @return [Array<ZapSMTP::WebhookEvent>]
1857
+ def verify_events(payload, headers, secret, **options)
1858
+ ZapSMTP::Webhook.verify_events(payload, headers, secret, **options)
1859
+ end
1860
+ end
1861
+
1862
+ # zap.templates.versions
1863
+ class TemplatesVersions
1864
+ # @api private
1865
+ def initialize(client)
1866
+ @client = client
1867
+ end
1868
+
1869
+ # List versions.
1870
+ #
1871
+ # List a template’s saved versions, newest first. Requires a full-access key. A version is recorded on
1872
+ # every create, update, publish and restore: kind is saved, published or restored. author is the
1873
+ # teammate’s email, or API key. The newest 50 versions are kept. List items leave out the bodies;
1874
+ # retrieve a version for them.
1875
+ #
1876
+ # @param id [String] Template id or alias.
1877
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1878
+ # @return [ZapSMTP::Page<ZapSMTP::Models::TemplateVersion>]
1879
+ def list(id, request_options: {})
1880
+ @client.request_page(
1881
+ method: :get,
1882
+ path: "/templates/#{Util.seg("id", id)}/versions",
1883
+ model: Models::TemplateVersion,
1884
+ paging: nil,
1885
+ request_options: request_options
1886
+ )
1887
+ end
1888
+
1889
+ # Retrieve a version.
1890
+ #
1891
+ # Retrieve one version with its bodies and design. Requires a full-access key. Empty html, text and from
1892
+ # are left out, and so is design for a code template.
1893
+ #
1894
+ # @param id [String] Template id or alias.
1895
+ # @param vid [String] Version id from the list.
1896
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1897
+ # @return [ZapSMTP::Models::TemplateVersion]
1898
+ def get(id, vid, request_options: {})
1899
+ @client.request(
1900
+ method: :get,
1901
+ path: "/templates/#{Util.seg("id", id)}/versions/#{Util.seg("vid", vid)}",
1902
+ model: Models::TemplateVersion,
1903
+ request_options: request_options
1904
+ )
1905
+ end
1906
+
1907
+ # Restore a version.
1908
+ #
1909
+ # Copy a version back into the draft. Publishing stays a separate step. Requires a full-access live key;
1910
+ # test keys get 403 test_key_restricted. Restores name, subject, html, text, from and design; alias and
1911
+ # sample variables stay. The restore is recorded as a version of kind restored. Sends keep using the
1912
+ # published version until you publish.
1913
+ #
1914
+ # @param id [String] Template id or alias.
1915
+ # @param vid [String] Version id from the list.
1916
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1917
+ # @return [ZapSMTP::Models::Template]
1918
+ def restore(id, vid, request_options: {})
1919
+ @client.request(
1920
+ method: :post,
1921
+ path: "/templates/#{Util.seg("id", id)}/versions/#{Util.seg("vid", vid)}/restore",
1922
+ model: Models::Template,
1923
+ request_options: request_options
1924
+ )
1925
+ end
1926
+ end
1927
+
1928
+ # zap.templates
1929
+ class Templates
1930
+ # @return [TemplatesVersions]
1931
+ attr_reader :versions
1932
+
1933
+ # @api private
1934
+ def initialize(client)
1935
+ @client = client
1936
+ @versions = TemplatesVersions.new(client)
1937
+ end
1938
+
1939
+ # List templates.
1940
+ #
1941
+ # List templates (most recently updated first). Requires a full-access key. variables are sample values
1942
+ # for previews; variable_names lists the variables used in the subject and bodies.
1943
+ #
1944
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1945
+ # @return [ZapSMTP::Page<ZapSMTP::Models::Template>]
1946
+ def list(request_options: {})
1947
+ @client.request_page(
1948
+ method: :get,
1949
+ path: "/templates",
1950
+ model: Models::Template,
1951
+ paging: nil,
1952
+ request_options: request_options
1953
+ )
1954
+ end
1955
+
1956
+ # Create a template.
1957
+ #
1958
+ # Create a template (logic-less Mustache). Requires a full-access live key; test keys get 403
1959
+ # test_key_restricted. Syntax: {{var}} escaped, {{{var}}} raw, {{#list}}…{{/list}} sections,
1960
+ # {{^x}}…{{/x}} inverted sections. Exact ordering of variable_names is determined by the parser; the
1961
+ # example order is illustrative. Body: html and text both empty → 422 missing_required_field; template
1962
+ # syntax errors → 422 template_render_error "<field>: <error>"; a tag that is not a variable name
1963
+ # ({{first name}}, {{#each items}}, {{> footer}}) → 422 template_render_error "html: line L, column C:
1964
+ # {{…}} is not a variable name: …" variable_schema in the response is the saved list after discovery. A
1965
+ # send is checked against the published copy, published.variable_schema.
1966
+ #
1967
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
1968
+ # @option params [String] :name Limits: trimmed, 1-200 characters → 422 missing_required_field "name is
1969
+ # required (max 200 chars)" Required.
1970
+ # @option params [String] :alias Stable handle usable instead of the id (template.id in sends,
1971
+ # /templates/{alias}). Limits: ^[a-z0-9][a-z0-9_-]{0,62}$ → 422 invalid_parameter; duplicate → 409
1972
+ # conflict
1973
+ # @option params [String] :subject Mustache source.
1974
+ # @option params [String] :html At least one of html and text is required. Mustache source; {{var}} is
1975
+ # HTML-escaped, {{{var}}} raw.
1976
+ # @option params [String] :text
1977
+ # @option params [String] :from Default From used when a send omits from.
1978
+ # @option params [Hash{String => Object}] :variables Sample variables used by previews. Never used for
1979
+ # sending; a variable first found in the source takes its sample as example.
1980
+ # @option params [Array<Hash>] :variable_schema Declares the template’s variables (see Variable schema).
1981
+ # Replaces the declared list when given. On every save, names the source uses that the list lacks are
1982
+ # added (their sample value as example): a section {{#x}} as optional any, a dotted {{x.y}} as a
1983
+ # required object, any other name as a required any, never stricter than sends were before, and declared
1984
+ # names the source no longer uses are kept with unused: true. Limits: at most 200 entries, no
1985
+ # duplicates, defaults and examples of their type → 422 invalid_parameter "variable_schema: <reason>"
1986
+ # @option params [Object] :design The visual editor’s document (a JSON object with a numeric version),
1987
+ # stored with the template. null makes it a code template. Changing html without sending design drops
1988
+ # the design (it no longer describes the HTML). Limits: max 1 MB → 422 invalid_parameter "design is
1989
+ # larger than 1 MB"; not an object with a numeric version → 422 invalid_parameter
1990
+ # @option params [Boolean] :publish Publish the result in the same call. Without it the template stays a
1991
+ # draft and is not used for sending until published. Default: false.
1992
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
1993
+ # @return [ZapSMTP::Models::Template]
1994
+ def create(params = {}, request_options: {}, **kwargs)
1995
+ @client.request(
1996
+ method: :post,
1997
+ path: "/templates",
1998
+ body: Util.params(params, kwargs),
1999
+ model: Models::Template,
2000
+ request_options: request_options
2001
+ )
2002
+ end
2003
+
2004
+ # Retrieve a template.
2005
+ #
2006
+ # Retrieve a template by id or alias. Requires a full-access key. id is what template.id takes when you
2007
+ # send; the alias works too. published is the version sends use (null until the first publish).
2008
+ # published.variable_schema is null for a template last published before variable schemas existed: its
2009
+ # sends need every variable, as before, until it is published again.
2010
+ #
2011
+ # @param id [String] Template id (UUID) or alias
2012
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2013
+ # @return [ZapSMTP::Models::Template]
2014
+ def get(id, request_options: {})
2015
+ @client.request(
2016
+ method: :get,
2017
+ path: "/templates/#{Util.seg("id", id)}",
2018
+ model: Models::Template,
2019
+ request_options: request_options
2020
+ )
2021
+ end
2022
+
2023
+ # Update a template.
2024
+ #
2025
+ # Update a template (partial). Requires a full-access live key; test keys get 403 test_key_restricted.
2026
+ # Fields left out keep their value; the same validation as create applies to the result. Every save (and
2027
+ # publish) is kept in the version history: see List versions. has_unpublished_changes is also true when
2028
+ # only the draft’s variable_schema differs from the published one.
2029
+ #
2030
+ # @param id [String] Template id or alias
2031
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
2032
+ # @option params [String] :name Limits: trimmed, 1-200 characters → 422 missing_required_field "name is
2033
+ # required (max 200 chars)"
2034
+ # @option params [String] :alias Stable handle; "" removes it usable instead of the id (template.id in
2035
+ # sends, /templates/{alias}). Limits: ^[a-z0-9][a-z0-9_-]{0,62}$ → 422 invalid_parameter; duplicate →
2036
+ # 409 conflict
2037
+ # @option params [String] :subject Mustache source.
2038
+ # @option params [String] :html Mustache source; {{var}} is HTML-escaped, {{{var}}} raw.
2039
+ # @option params [String] :text
2040
+ # @option params [String] :from Default From used when a send omits from.
2041
+ # @option params [Hash{String => Object}] :variables Sample variables used by previews; replaces the
2042
+ # whole object. Never used for sending; a variable first found in the source takes its sample as
2043
+ # example.
2044
+ # @option params [Array<Hash>] :variable_schema Declares the template’s variables (see Variable schema).
2045
+ # Replaces the declared list when given. On every save, names the source uses that the list lacks are
2046
+ # added (their sample value as example): a section {{#x}} as optional any, a dotted {{x.y}} as a
2047
+ # required object, any other name as a required any, never stricter than sends were before, and declared
2048
+ # names the source no longer uses are kept with unused: true. Limits: at most 200 entries, no
2049
+ # duplicates, defaults and examples of their type → 422 invalid_parameter "variable_schema: <reason>"
2050
+ # @option params [Object] :design The visual editor’s document (a JSON object with a numeric version),
2051
+ # stored with the template. null makes it a code template. Changing html without sending design drops
2052
+ # the design (it no longer describes the HTML). Limits: max 1 MB → 422 invalid_parameter "design is
2053
+ # larger than 1 MB"; not an object with a numeric version → 422 invalid_parameter
2054
+ # @option params [Boolean] :publish Publish the result in the same call. Without it the template stays a
2055
+ # draft and is not used for sending until published. Default: false.
2056
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2057
+ # @return [ZapSMTP::Models::Template]
2058
+ def update(id, params = {}, request_options: {}, **kwargs)
2059
+ @client.request(
2060
+ method: :patch,
2061
+ path: "/templates/#{Util.seg("id", id)}",
2062
+ body: Util.params(params, kwargs),
2063
+ model: Models::Template,
2064
+ request_options: request_options
2065
+ )
2066
+ end
2067
+
2068
+ # Delete a template.
2069
+ #
2070
+ # Delete a template. Requires a full-access live key; test keys get 403 test_key_restricted.
2071
+ #
2072
+ # @param id [String] Template id or alias
2073
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2074
+ # @return [ZapSMTP::Models::Deleted]
2075
+ def delete(id, request_options: {})
2076
+ @client.request(
2077
+ method: :delete,
2078
+ path: "/templates/#{Util.seg("id", id)}",
2079
+ model: Models::Deleted,
2080
+ request_options: request_options
2081
+ )
2082
+ end
2083
+
2084
+ # Render a template.
2085
+ #
2086
+ # Preview a stored template with given variables (defaults to its sample variables). Requires a
2087
+ # full-access key. Missing variables do not fail the preview; they are listed in missing_variables.
2088
+ #
2089
+ # @param id [String] Template id or alias
2090
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
2091
+ # @option params [Hash{String => Object}] :variables Variables to render with; when omitted the
2092
+ # template's stored sample variables are used.
2093
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2094
+ # @return [ZapSMTP::Models::RenderedTemplate]
2095
+ def render(id, params = {}, request_options: {}, **kwargs)
2096
+ @client.request(
2097
+ method: :post,
2098
+ path: "/templates/#{Util.seg("id", id)}/render",
2099
+ body: Util.params(params, kwargs),
2100
+ model: Models::RenderedTemplate,
2101
+ request_options: request_options
2102
+ )
2103
+ end
2104
+
2105
+ # Render unsaved source.
2106
+ #
2107
+ # Validate and preview unsaved template source. Requires a full-access key.
2108
+ #
2109
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
2110
+ # @option params [String] :subject
2111
+ # @option params [String] :html
2112
+ # @option params [String] :text
2113
+ # @option params [Hash{String => Object}] :variables Default: {}.
2114
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2115
+ # @return [ZapSMTP::Models::RenderedTemplate]
2116
+ def render_source(params = {}, request_options: {}, **kwargs)
2117
+ @client.request(
2118
+ method: :post,
2119
+ path: "/templates/render",
2120
+ body: Util.params(params, kwargs),
2121
+ model: Models::RenderedTemplate,
2122
+ request_options: request_options
2123
+ )
2124
+ end
2125
+
2126
+ # Publish a template.
2127
+ #
2128
+ # Make the current draft the version sends use. Until a template is published, sending with it fails.
2129
+ # Requires a full-access live key; test keys get 403 test_key_restricted.
2130
+ #
2131
+ # @param id [String] Template id or alias.
2132
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2133
+ # @return [ZapSMTP::Models::Template]
2134
+ def publish(id, request_options: {})
2135
+ @client.request(
2136
+ method: :post,
2137
+ path: "/templates/#{Util.seg("id", id)}/publish",
2138
+ model: Models::Template,
2139
+ request_options: request_options
2140
+ )
2141
+ end
2142
+
2143
+ # Duplicate a template.
2144
+ #
2145
+ # Copy a template’s draft into a new, unpublished template named “… (copy)”, without the alias. Requires
2146
+ # a full-access live key; test keys get 403 test_key_restricted.
2147
+ #
2148
+ # @param id [String] Template id or alias.
2149
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2150
+ # @return [ZapSMTP::Models::Template]
2151
+ def duplicate(id, request_options: {})
2152
+ @client.request(
2153
+ method: :post,
2154
+ path: "/templates/#{Util.seg("id", id)}/duplicate",
2155
+ model: Models::Template,
2156
+ request_options: request_options
2157
+ )
2158
+ end
2159
+ end
2160
+
2161
+ # zap.suppressions
2162
+ class Suppressions
2163
+ # @api private
2164
+ def initialize(client)
2165
+ @client = client
2166
+ end
2167
+
2168
+ # List suppressions.
2169
+ #
2170
+ # List suppressed addresses, newest first, with cursor pagination. Requires a full-access key. reason is
2171
+ # hard_bounce, complaint, unsubscribe or manual; source_id is the email that caused it (null when added
2172
+ # by hand). Pass next_cursor as after for the next page. unsubscribe stops only broadcast email (stream:
2173
+ # broadcast); transactional email to the address still goes out. Every other reason stops all email to
2174
+ # it.
2175
+ #
2176
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
2177
+ # @option params [Integer] :limit 1-1000; out-of-range falls back to 100. Default: 100.
2178
+ # @option params [String] :after Opaque cursor from next_cursor. Limits: 422 invalid_parameter "invalid
2179
+ # after cursor"
2180
+ # @option params [String] :before Legacy: RFC 3339 timestamp; returns entries created before it. Ignored
2181
+ # when after is set. Limits: 422 invalid_parameter "before must be RFC3339"
2182
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2183
+ # @return [ZapSMTP::Page<ZapSMTP::Models::Suppression>]
2184
+ def list(params = {}, request_options: {}, **kwargs)
2185
+ @client.request_page(
2186
+ method: :get,
2187
+ path: "/suppressions",
2188
+ query: Util.params(params, kwargs),
2189
+ model: Models::Suppression,
2190
+ paging: :cursor,
2191
+ request_options: request_options
2192
+ )
2193
+ end
2194
+
2195
+ # Add a suppression.
2196
+ #
2197
+ # Add an address to the suppression list. Requires a full-access live key; test keys get 403
2198
+ # test_key_restricted. Idempotent: an existing entry keeps its reason, except that an unsubscribe entry
2199
+ # becomes manual when you add it as manual (a later bounce or complaint upgrades it the same way). The
2200
+ # response echoes the requested reason with 201.
2201
+ #
2202
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
2203
+ # @option params [String] :email Address (stored lowercased). Limits: 422 invalid_parameter "invalid
2204
+ # email" Required.
2205
+ # @option params [String] :reason manual: no email at all; unsubscribe: no broadcast email
2206
+ # (transactional email still goes out). Limits: 422 invalid_parameter "reason must be manual or
2207
+ # unsubscribe" One of: manual, unsubscribe. Default: manual.
2208
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2209
+ # @return [ZapSMTP::Models::Suppression]
2210
+ def create(params = {}, request_options: {}, **kwargs)
2211
+ @client.request(
2212
+ method: :post,
2213
+ path: "/suppressions",
2214
+ body: Util.params(params, kwargs),
2215
+ model: Models::Suppression,
2216
+ request_options: request_options
2217
+ )
2218
+ end
2219
+
2220
+ # Remove a suppression.
2221
+ #
2222
+ # Remove an address from the suppression list. Requires a full-access live key; test keys get 403
2223
+ # test_key_restricted.
2224
+ #
2225
+ # @param email [String] Address (URL-encoded; matched case-insensitively)
2226
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2227
+ # @return [nil]
2228
+ def delete(email, request_options: {})
2229
+ @client.request(
2230
+ method: :delete,
2231
+ path: "/suppressions/#{Util.seg("email", email)}",
2232
+ model: nil,
2233
+ request_options: request_options
2234
+ )
2235
+ end
2236
+
2237
+ # Retrieve a suppression.
2238
+ #
2239
+ # Check whether one address is suppressed, and why. Requires a full-access key. unsubscribe stops only
2240
+ # broadcast email (stream: broadcast); transactional email to the address still goes out. Every other
2241
+ # reason stops all email to it.
2242
+ #
2243
+ # @param email [String] The address (case-insensitive, URL-encoded).
2244
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2245
+ # @return [ZapSMTP::Models::Suppression]
2246
+ def get(email, request_options: {})
2247
+ @client.request(
2248
+ method: :get,
2249
+ path: "/suppressions/#{Util.seg("email", email)}",
2250
+ model: Models::Suppression,
2251
+ request_options: request_options
2252
+ )
2253
+ end
2254
+
2255
+ # Add suppressions in bulk.
2256
+ #
2257
+ # Add up to 1,000 addresses in one call. Duplicates are ignored; existing entries keep their reason (an
2258
+ # unsubscribe becomes manual when added as manual); sends see the change immediately. Requires a
2259
+ # full-access live key; test keys get 403 test_key_restricted.
2260
+ #
2261
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
2262
+ # @option params [Array<String>] :emails 1–1,000 addresses. Required.
2263
+ # @option params [String] :reason manual: no email at all; unsubscribe: no broadcast email
2264
+ # (transactional email still goes out). One of: manual, unsubscribe. Default: manual.
2265
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2266
+ # @return [ZapSMTP::Models::SuppressionBatch]
2267
+ def create_batch(params = {}, request_options: {}, **kwargs)
2268
+ @client.request(
2269
+ method: :post,
2270
+ path: "/suppressions/batch",
2271
+ body: Util.params(params, kwargs),
2272
+ model: Models::SuppressionBatch,
2273
+ request_options: request_options
2274
+ )
2275
+ end
2276
+
2277
+ # Remove suppressions in bulk.
2278
+ #
2279
+ # Remove up to 1,000 addresses in one call. Addresses that are not on the list are ignored. Requires a
2280
+ # full-access live key; test keys get 403 test_key_restricted.
2281
+ #
2282
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
2283
+ # @option params [Array<String>] :emails 1–1,000 addresses. Required.
2284
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2285
+ # @return [ZapSMTP::Models::SuppressionBatch]
2286
+ def delete_batch(params = {}, request_options: {}, **kwargs)
2287
+ @client.request(
2288
+ method: :post,
2289
+ path: "/suppressions/batch/remove",
2290
+ body: Util.params(params, kwargs),
2291
+ model: Models::SuppressionBatch,
2292
+ request_options: request_options
2293
+ )
2294
+ end
2295
+ end
2296
+
2297
+ # zap.dedicated_ips
2298
+ class DedicatedIps
2299
+ # @api private
2300
+ def initialize(client)
2301
+ @client = client
2302
+ end
2303
+
2304
+ # List dedicated IPs.
2305
+ #
2306
+ # List the account's dedicated IPs with warm-up progress and current blocklist listings. Requires a
2307
+ # full-access key. status is warming, active or paused. During warm-up, warmup_day and daily_cap show
2308
+ # the current day and today’s volume limit. blocklists lists current listings of the IP.
2309
+ #
2310
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2311
+ # @return [ZapSMTP::Page<ZapSMTP::Models::DedicatedIp>]
2312
+ def list(request_options: {})
2313
+ @client.request_page(
2314
+ method: :get,
2315
+ path: "/dedicated-ips",
2316
+ model: Models::DedicatedIp,
2317
+ paging: nil,
2318
+ request_options: request_options
2319
+ )
2320
+ end
2321
+ end
2322
+
2323
+ # zap.logs
2324
+ class Logs
2325
+ # @api private
2326
+ def initialize(client)
2327
+ @client = client
2328
+ end
2329
+
2330
+ # List logs.
2331
+ #
2332
+ # List the API requests made with your keys, newest first. Bodies are on Retrieve a log. Entries appear
2333
+ # within seconds and are kept for your plan’s log retention. Requires a full-access key. Requests made
2334
+ # with API keys are logged; the dashboard’s own calls are not. The X-Request-Id header of every response
2335
+ # is the id of its log entry.
2336
+ #
2337
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
2338
+ # @option params [Integer] :limit 1–100. Default: 20.
2339
+ # @option params [String] :before A log id: return older entries.
2340
+ # @option params [String] :after A log id: return newer entries.
2341
+ # @option params [String] :status An exact status (422) or a class: 2xx, 4xx, 5xx.
2342
+ # @option params [String] :method HTTP method.
2343
+ # @option params [String] :path Path prefix, e.g. /v1/emails.
2344
+ # @option params [String] :api_key_id Only requests made with this key.
2345
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2346
+ # @return [ZapSMTP::Page<ZapSMTP::Models::Log>]
2347
+ def list(params = {}, request_options: {}, **kwargs)
2348
+ @client.request_page(
2349
+ method: :get,
2350
+ path: "/logs",
2351
+ query: Util.params(params, kwargs),
2352
+ model: Models::Log,
2353
+ paging: :logs,
2354
+ request_options: request_options
2355
+ )
2356
+ end
2357
+
2358
+ # Retrieve a log.
2359
+ #
2360
+ # Retrieve one request with its request and response bodies. Bodies are capped at 16 KB; API keys,
2361
+ # passwords and signing secrets are always replaced with [redacted]. Requires a full-access key.
2362
+ #
2363
+ # @param id [String] Log id (the X-Request-Id of the response).
2364
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2365
+ # @return [ZapSMTP::Models::Log]
2366
+ def get(id, request_options: {})
2367
+ @client.request(
2368
+ method: :get,
2369
+ path: "/logs/#{Util.seg("id", id)}",
2370
+ model: Models::Log,
2371
+ request_options: request_options
2372
+ )
2373
+ end
2374
+ end
2375
+
2376
+ # zap.usage
2377
+ class Usage
2378
+ # @api private
2379
+ def initialize(client)
2380
+ @client = client
2381
+ end
2382
+
2383
+ # Retrieve usage.
2384
+ #
2385
+ # This month’s sending against your plan: emails sent, included volume, limit, overage and, on the Free
2386
+ # plan, today’s count. Requires a full-access key. limit is null on paid plans without a spending cap:
2387
+ # email keeps flowing and extra volume is billed. The Free plan adds daily_limit and sent_today.
2388
+ #
2389
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2390
+ # @return [ZapSMTP::Models::Usage]
2391
+ def get(request_options: {})
2392
+ @client.request(method: :get, path: "/usage", model: Models::Usage, request_options: request_options)
2393
+ end
2394
+ end
2395
+
2396
+ # zap.template_modules
2397
+ class TemplateModules
2398
+ # @api private
2399
+ def initialize(client)
2400
+ @client = client
2401
+ end
2402
+
2403
+ # List modules.
2404
+ #
2405
+ # List saved modules (reusable rows for the visual editor), most recently updated first. Requires a
2406
+ # full-access key. All modules of the account in one page (has_more is always false).
2407
+ #
2408
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2409
+ # @return [ZapSMTP::Page<ZapSMTP::Models::TemplateModule>]
2410
+ def list(request_options: {})
2411
+ @client.request_page(
2412
+ method: :get,
2413
+ path: "/template-modules",
2414
+ model: Models::TemplateModule,
2415
+ paging: nil,
2416
+ request_options: request_options
2417
+ )
2418
+ end
2419
+
2420
+ # Save a module.
2421
+ #
2422
+ # Save rows as a module that every template of the account can insert. Requires a full-access live key;
2423
+ # test keys get 403 test_key_restricted. Inserting a module copies its rows into the template: changing
2424
+ # the module later does not change templates that already use it.
2425
+ #
2426
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
2427
+ # @option params [String] :name Limits: trimmed, 1-200 characters → 422 missing_required_field Required.
2428
+ # @option params [String] :category Groups modules in the editor’s palette. Limits: trimmed, max 100
2429
+ # characters → 422 missing_required_field Default: "".
2430
+ # @option params [Object] :design The saved rows: {"rows": [...]} with at least one row in the visual
2431
+ # editor’s format (copy rows from a template’s design). Limits: max 1 MB → 422 invalid_parameter
2432
+ # Required.
2433
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2434
+ # @return [ZapSMTP::Models::TemplateModule]
2435
+ def create(params = {}, request_options: {}, **kwargs)
2436
+ @client.request(
2437
+ method: :post,
2438
+ path: "/template-modules",
2439
+ body: Util.params(params, kwargs),
2440
+ model: Models::TemplateModule,
2441
+ request_options: request_options
2442
+ )
2443
+ end
2444
+
2445
+ # Retrieve a module.
2446
+ #
2447
+ # Retrieve a module. Requires a full-access key.
2448
+ #
2449
+ # @param id [String] Module id.
2450
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2451
+ # @return [ZapSMTP::Models::TemplateModule]
2452
+ def get(id, request_options: {})
2453
+ @client.request(
2454
+ method: :get,
2455
+ path: "/template-modules/#{Util.seg("id", id)}",
2456
+ model: Models::TemplateModule,
2457
+ request_options: request_options
2458
+ )
2459
+ end
2460
+
2461
+ # Update a module.
2462
+ #
2463
+ # Rename, recategorize or replace a module’s rows. Requires a full-access live key; test keys get 403
2464
+ # test_key_restricted. Fields left out keep their value.
2465
+ #
2466
+ # @param id [String] Module id.
2467
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
2468
+ # @option params [String] :name Limits: trimmed, 1-200 characters → 422 missing_required_field
2469
+ # @option params [String] :category Groups modules in the editor’s palette. Limits: trimmed, max 100
2470
+ # characters → 422 missing_required_field
2471
+ # @option params [Object] :design The saved rows: {"rows": [...]} with at least one row in the visual
2472
+ # editor’s format (copy rows from a template’s design). Limits: max 1 MB → 422 invalid_parameter
2473
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2474
+ # @return [ZapSMTP::Models::TemplateModule]
2475
+ def update(id, params = {}, request_options: {}, **kwargs)
2476
+ @client.request(
2477
+ method: :patch,
2478
+ path: "/template-modules/#{Util.seg("id", id)}",
2479
+ body: Util.params(params, kwargs),
2480
+ model: Models::TemplateModule,
2481
+ request_options: request_options
2482
+ )
2483
+ end
2484
+
2485
+ # Delete a module.
2486
+ #
2487
+ # Delete a module. Templates that inserted it keep their copy. Requires a full-access live key; test
2488
+ # keys get 403 test_key_restricted.
2489
+ #
2490
+ # @param id [String] Module id.
2491
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2492
+ # @return [ZapSMTP::Models::Deleted]
2493
+ def delete(id, request_options: {})
2494
+ @client.request(
2495
+ method: :delete,
2496
+ path: "/template-modules/#{Util.seg("id", id)}",
2497
+ model: Models::Deleted,
2498
+ request_options: request_options
2499
+ )
2500
+ end
2501
+ end
2502
+
2503
+ # zap.template_assets
2504
+ class TemplateAssets
2505
+ # @api private
2506
+ def initialize(client)
2507
+ @client = client
2508
+ end
2509
+
2510
+ # List images.
2511
+ #
2512
+ # List the account’s template images, newest first. Requires a full-access key. All images of the
2513
+ # account in one page (has_more is always false).
2514
+ #
2515
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2516
+ # @return [ZapSMTP::Page<ZapSMTP::Models::TemplateAsset>]
2517
+ def list(request_options: {})
2518
+ @client.request_page(
2519
+ method: :get,
2520
+ path: "/template-assets",
2521
+ model: Models::TemplateAsset,
2522
+ paging: nil,
2523
+ request_options: request_options
2524
+ )
2525
+ end
2526
+
2527
+ # Upload an image.
2528
+ #
2529
+ # Upload an image for use in templates, as a multipart file or by URL; returns its public URL. Requires
2530
+ # a full-access live key; test keys get 403 test_key_restricted. PNG, JPEG, GIF or WebP, up to 5 MB and
2531
+ # 40 megapixels; the file content decides the type, not its name. PNG and JPEG images wider than 1,200
2532
+ # px are scaled down to 1,200 px (twice a 600 px email); GIF (animations included) and WebP are kept as
2533
+ # they are. width and height are those of the stored image. The URL is public (anyone with it can load
2534
+ # the image) and long-lived: use it in <img src> of any template. The name keeps letters, digits, spaces
2535
+ # and . _ ( ) -, up to 200 characters. Each account holds up to 2,000 images and 1 GB.
2536
+ #
2537
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
2538
+ # @option params [String] :url JSON upload: an http(s) URL we download the image from (private and
2539
+ # internal addresses are refused). Limits: unreachable, not HTTP 200 or not a URL → 422
2540
+ # invalid_parameter Required.
2541
+ # @option params [String] :name JSON upload: the file name shown in the image library. Default: the last
2542
+ # segment of the URL.
2543
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2544
+ # @return [ZapSMTP::Models::TemplateAsset]
2545
+ def upload(params = {}, request_options: {}, **kwargs)
2546
+ @client.request(
2547
+ method: :post,
2548
+ path: "/template-assets",
2549
+ body: Util.params(params, kwargs),
2550
+ model: Models::TemplateAsset,
2551
+ request_options: request_options
2552
+ )
2553
+ end
2554
+
2555
+ # Upload an image, from a file: PNG, JPEG, GIF or WebP bytes sent as multipart/form-data.
2556
+ #
2557
+ # @param file [String, Pathname, IO] a file path, or an IO (File, StringIO, Tempfile) to read
2558
+ # @param name [String, nil] the file name shown in the image library
2559
+ # @param filename [String, nil] the file name sent with the upload (default: name, else the file's own
2560
+ # name)
2561
+ # @param request_options [Hash] :headers, :timeout and :max_retries for this call
2562
+ # @return [ZapSMTP::Models::TemplateAsset]
2563
+ def upload_file(file, name: nil, filename: nil, request_options: {})
2564
+ @client.request(
2565
+ method: :post,
2566
+ path: "/template-assets",
2567
+ form: Util.upload_form("file", file, name: name, filename: filename),
2568
+ model: Models::TemplateAsset,
2569
+ request_options: request_options
2570
+ )
2571
+ end
2572
+
2573
+ # Delete an image.
2574
+ #
2575
+ # Delete an image. Its URL stops working, also in emails already sent. Requires a full-access live key;
2576
+ # test keys get 403 test_key_restricted.
2577
+ #
2578
+ # @param id [String] Image id.
2579
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2580
+ # @return [ZapSMTP::Models::Deleted]
2581
+ def delete(id, request_options: {})
2582
+ @client.request(
2583
+ method: :delete,
2584
+ path: "/template-assets/#{Util.seg("id", id)}",
2585
+ model: Models::Deleted,
2586
+ request_options: request_options
2587
+ )
2588
+ end
2589
+ end
2590
+
2591
+ # zap.template_timers
2592
+ class TemplateTimers
2593
+ # @api private
2594
+ def initialize(client)
2595
+ @client = client
2596
+ end
2597
+
2598
+ # Create a countdown timer.
2599
+ #
2600
+ # Create a countdown timer image: an animated GIF that shows the time left whenever the email is opened.
2601
+ # Requires a full-access live key; test keys get 403 test_key_restricted. Nothing is stored: the URL
2602
+ # carries the signed settings, so changing it breaks the image. Put it in an <img> of a template (the
2603
+ # visual editor’s timer block does this for you). Each open renders one frame per second for a minute,
2604
+ # then the last frame stays; after end it shows zeros. Renders are shared for 5 seconds, so a broadcast
2605
+ # opened by many recipients at once costs one render.
2606
+ #
2607
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
2608
+ # @option params [String] :end When the countdown reaches zero. Limits: missing → 422 invalid_parameter
2609
+ # "end is required"; not RFC 3339 → 400 validation_error Required.
2610
+ # @option params [Integer] :width Image width in px, 200-600; the height follows. Limits: otherwise 422
2611
+ # invalid_parameter "w must be 200–600" Default: 600.
2612
+ # @option params [String] :digit_color Digit colour, hex RRGGBB or RRGGBBAA (a leading # is allowed).
2613
+ # Limits: otherwise 422 invalid_parameter "fg: colour must be RRGGBB or RRGGBBAA" Required.
2614
+ # @option params [String] :label_color Label colour, same format. Limits: 422 invalid_parameter "lc: …"
2615
+ # Required.
2616
+ # @option params [String] :background Background colour, same format; alpha 00 (e.g. ffffff00) is
2617
+ # transparent. Limits: 422 invalid_parameter "bg: …" Required.
2618
+ # @option params [Array<String>] :labels Exactly 4 labels under days, hours, minutes and seconds, each
2619
+ # up to 12 characters, without |. "" hides one label; four empty labels hide the label row. Limits: 422
2620
+ # invalid_parameter "l must hold 4 labels separated by |" / "labels are limited to 12 characters"
2621
+ # Default: ["days", "hours", "minutes", "seconds"].
2622
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2623
+ # @return [ZapSMTP::Models::TemplateTimer]
2624
+ def create(params = {}, request_options: {}, **kwargs)
2625
+ @client.request(
2626
+ method: :post,
2627
+ path: "/template-timers",
2628
+ body: Util.params(params, kwargs),
2629
+ model: Models::TemplateTimer,
2630
+ request_options: request_options
2631
+ )
2632
+ end
2633
+ end
2634
+
2635
+ # zap.actions
2636
+ class Actions
2637
+ # @api private
2638
+ def initialize(client)
2639
+ @client = client
2640
+ end
2641
+
2642
+ # List actions.
2643
+ #
2644
+ # List every action of the account: the ones you declared, the ones links named in the last 30 days, and
2645
+ # the ones templates and webhook filters use. Sorted by name. Requires a full-access key. declared is
2646
+ # false for an action that links use but nobody described; created_at and updated_at are then null.
2647
+ # clicks_7d, clicks_30d and unique_clickers_30d (distinct email and recipient pairs) count the last 7
2648
+ # and 30 days; last_click_at is null without a click in 30 days. templates counts the templates whose
2649
+ # draft or published HTML names the action; webhooks lists the ids of the endpoints filtered on it.
2650
+ #
2651
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2652
+ # @return [ZapSMTP::Page<ZapSMTP::Models::Action>]
2653
+ def list(request_options: {})
2654
+ @client.request_page(
2655
+ method: :get,
2656
+ path: "/actions",
2657
+ model: Models::Action,
2658
+ paging: nil,
2659
+ request_options: request_options
2660
+ )
2661
+ end
2662
+
2663
+ # Declare an action.
2664
+ #
2665
+ # Declare an action and describe it. Optional: links work with any valid name, declared or not. Requires
2666
+ # a full-access live key; test keys get 403 test_key_restricted. The response does not count activity:
2667
+ # the stats are zero and templates is 0 here. Read them with GET /actions/{name}.
2668
+ #
2669
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
2670
+ # @option params [String] :name The name links carry in data-zap-action: lowercase letters, digits, _, .
2671
+ # and -, starting with a letter or digit, up to 64 characters. Limits: other names → 422
2672
+ # invalid_parameter Required.
2673
+ # @option params [String] :description What the button does, for your team. Limits: at most 500 bytes →
2674
+ # 422 invalid_parameter
2675
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2676
+ # @return [ZapSMTP::Models::Action]
2677
+ def create(params = {}, request_options: {}, **kwargs)
2678
+ @client.request(
2679
+ method: :post,
2680
+ path: "/actions",
2681
+ body: Util.params(params, kwargs),
2682
+ model: Models::Action,
2683
+ request_options: request_options
2684
+ )
2685
+ end
2686
+
2687
+ # Retrieve an action.
2688
+ #
2689
+ # Retrieve one action from the catalogue, with its activity and where it is used. Requires a full-access
2690
+ # key.
2691
+ #
2692
+ # @param name [String] Action name, as written in data-zap-action.
2693
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2694
+ # @return [ZapSMTP::Models::Action]
2695
+ def get(name, request_options: {})
2696
+ @client.request(
2697
+ method: :get,
2698
+ path: "/actions/#{Util.seg("name", name)}",
2699
+ model: Models::Action,
2700
+ request_options: request_options
2701
+ )
2702
+ end
2703
+
2704
+ # Describe an action.
2705
+ #
2706
+ # Change an action’s description. An action that links use but nobody declared is declared by this call.
2707
+ # Requires a full-access live key; test keys get 403 test_key_restricted. Like create, the response
2708
+ # carries zero stats; read them with GET /actions/{name}.
2709
+ #
2710
+ # @param name [String] Action name, as written in data-zap-action.
2711
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
2712
+ # @option params [String] :description The new description; leaving it out sets it to empty. Limits: at
2713
+ # most 500 bytes → 422 invalid_parameter
2714
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2715
+ # @return [ZapSMTP::Models::Action]
2716
+ def update(name, params = {}, request_options: {}, **kwargs)
2717
+ @client.request(
2718
+ method: :patch,
2719
+ path: "/actions/#{Util.seg("name", name)}",
2720
+ body: Util.params(params, kwargs),
2721
+ model: Models::Action,
2722
+ request_options: request_options
2723
+ )
2724
+ end
2725
+
2726
+ # Delete an action.
2727
+ #
2728
+ # Delete an action’s declaration. Links that name it keep working: clicks are still tracked and still
2729
+ # reach webhooks filtered on it. Requires a full-access live key; test keys get 403 test_key_restricted.
2730
+ # While links or webhooks still use it, the action stays in the catalogue with declared: false.
2731
+ #
2732
+ # @param name [String] Action name, as written in data-zap-action.
2733
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2734
+ # @return [ZapSMTP::Models::Deleted]
2735
+ def delete(name, request_options: {})
2736
+ @client.request(
2737
+ method: :delete,
2738
+ path: "/actions/#{Util.seg("name", name)}",
2739
+ model: Models::Deleted,
2740
+ request_options: request_options
2741
+ )
2742
+ end
2743
+ end
2744
+
2745
+ # zap.variables
2746
+ class Variables
2747
+ # @api private
2748
+ def initialize(client)
2749
+ @client = client
2750
+ end
2751
+
2752
+ # List variables.
2753
+ #
2754
+ # The variable catalogue: every variable the account’s templates can use, with where each is used.
2755
+ # System variables first, then global ones, then template variables, each sorted by name. Requires a
2756
+ # full-access key. kind is system (filled by ZapSMTP), global (set for the account, written
2757
+ # {{global.key}}) or template (a template’s own). A global variable that templates use but that has no
2758
+ # value yet is listed without value; sends with those templates fail until you set it. A template
2759
+ # variable lists in types every type its templates declare, and per template its type, required, default
2760
+ # and unused (declared, but the source no longer names it).
2761
+ #
2762
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2763
+ # @return [ZapSMTP::Page<ZapSMTP::Models::Variable>]
2764
+ def list(request_options: {})
2765
+ @client.request_page(
2766
+ method: :get,
2767
+ path: "/variables",
2768
+ model: Models::Variable,
2769
+ paging: nil,
2770
+ request_options: request_options
2771
+ )
2772
+ end
2773
+
2774
+ # Set a global variable.
2775
+ #
2776
+ # Create or replace a global variable. Every template that uses it renders the new value from the next
2777
+ # send on. Requires a full-access live key; test keys get 403 test_key_restricted. The response does not
2778
+ # list the templates using the variable; GET /variables does.
2779
+ #
2780
+ # @param key [String] The key, used as {{global.key}}: letters, digits, _ and -, starting with a letter
2781
+ # or _, up to 64; global is reserved. Limits: other keys → 422 invalid_parameter
2782
+ # @param params [Hash] the parameters below, also accepted as keyword arguments
2783
+ # @option params [String] :value The value, always a string. Limits: at most 10 KB → 422
2784
+ # invalid_parameter Default: "".
2785
+ # @option params [String] :description What it is for. Limits: at most 500 bytes → 422 invalid_parameter
2786
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2787
+ # @return [ZapSMTP::Models::Variable]
2788
+ def set_global(key, params = {}, request_options: {}, **kwargs)
2789
+ @client.request(
2790
+ method: :put,
2791
+ path: "/variables/global/#{Util.seg("key", key)}",
2792
+ body: Util.params(params, kwargs),
2793
+ model: Models::Variable,
2794
+ request_options: request_options
2795
+ )
2796
+ end
2797
+
2798
+ # Delete a global variable.
2799
+ #
2800
+ # Delete a global variable. Sends with a template that still uses it then fail with 422
2801
+ # template_render_error until it is set again. Requires a full-access live key; test keys get 403
2802
+ # test_key_restricted.
2803
+ #
2804
+ # @param key [String] The key, used as {{global.key}}: letters, digits, _ and -, starting with a letter
2805
+ # or _, up to 64; global is reserved. Limits: other keys → 422 invalid_parameter
2806
+ # @param request_options [Hash] :idempotency_key, :headers, :timeout and :max_retries for this call
2807
+ # @return [ZapSMTP::Models::Deleted]
2808
+ def delete_global(key, request_options: {})
2809
+ @client.request(
2810
+ method: :delete,
2811
+ path: "/variables/global/#{Util.seg("key", key)}",
2812
+ model: Models::Deleted,
2813
+ request_options: request_options
2814
+ )
2815
+ end
2816
+ end
2817
+ end
2818
+ end