lockally 0.3.1 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +7 -5
  3. data/docs/AdminApi.md +3 -3
  4. data/docs/AdminsApi.md +1 -1
  5. data/docs/AgentSendResult.md +6 -2
  6. data/docs/AgentsApi.md +2 -2
  7. data/docs/AiApi.md +1 -1
  8. data/docs/AliasesApi.md +1 -1
  9. data/docs/ApiKeysApi.md +3 -3
  10. data/docs/DomainsApi.md +3 -3
  11. data/docs/MailboxGrant.md +7 -3
  12. data/docs/MailboxGrantList.md +2 -2
  13. data/docs/MailboxesApi.md +6 -6
  14. data/docs/MarkReadResult.md +2 -0
  15. data/docs/SendApi.md +4 -4
  16. data/docs/SimulatedInbound.md +6 -0
  17. data/docs/TenantApi.md +1 -1
  18. data/docs/TestApi.md +1 -1
  19. data/docs/ThreadClassification.md +2 -0
  20. data/docs/ThreadMessageBody.md +10 -26
  21. data/docs/{ThreadMessageBodyAllOfBody.md → ThreadMessageBodyBody.md} +2 -2
  22. data/docs/WebhooksApi.md +3 -3
  23. data/docs/Whoami.md +7 -7
  24. data/docs/WhoamiKey.md +20 -0
  25. data/docs/WhoamiTenant.md +22 -0
  26. data/lib/lockally/api/admin_api.rb +6 -6
  27. data/lib/lockally/api/admins_api.rb +2 -2
  28. data/lib/lockally/api/agents_api.rb +4 -4
  29. data/lib/lockally/api/ai_api.rb +2 -2
  30. data/lib/lockally/api/aliases_api.rb +2 -2
  31. data/lib/lockally/api/api_keys_api.rb +6 -6
  32. data/lib/lockally/api/domains_api.rb +6 -6
  33. data/lib/lockally/api/mailboxes_api.rb +12 -12
  34. data/lib/lockally/api/send_api.rb +8 -8
  35. data/lib/lockally/api/tenant_api.rb +2 -2
  36. data/lib/lockally/api/test_api.rb +2 -2
  37. data/lib/lockally/api/webhooks_api.rb +6 -6
  38. data/lib/lockally/models/agent_send_result.rb +72 -1
  39. data/lib/lockally/models/mailbox_grant.rb +28 -10
  40. data/lib/lockally/models/mailbox_grant_list.rb +17 -17
  41. data/lib/lockally/models/mark_read_result.rb +10 -1
  42. data/lib/lockally/models/simulated_inbound.rb +29 -1
  43. data/lib/lockally/models/thread_classification.rb +11 -1
  44. data/lib/lockally/models/thread_message_body.rb +58 -233
  45. data/lib/lockally/models/{thread_message_body_all_of_body.rb → thread_message_body_body.rb} +4 -3
  46. data/lib/lockally/models/whoami.rb +98 -24
  47. data/lib/lockally/models/whoami_key.rb +157 -0
  48. data/lib/lockally/models/whoami_tenant.rb +166 -0
  49. data/lib/lockally/version.rb +1 -1
  50. data/lib/lockally.rb +3 -1
  51. data/spec/api/admin_api_spec.rb +3 -3
  52. data/spec/api/admins_api_spec.rb +1 -1
  53. data/spec/api/agents_api_spec.rb +2 -2
  54. data/spec/api/ai_api_spec.rb +1 -1
  55. data/spec/api/aliases_api_spec.rb +1 -1
  56. data/spec/api/api_keys_api_spec.rb +3 -3
  57. data/spec/api/domains_api_spec.rb +3 -3
  58. data/spec/api/mailboxes_api_spec.rb +6 -6
  59. data/spec/api/send_api_spec.rb +4 -4
  60. data/spec/api/tenant_api_spec.rb +1 -1
  61. data/spec/api/test_api_spec.rb +1 -1
  62. data/spec/api/webhooks_api_spec.rb +3 -3
  63. data/spec/models/agent_send_result_spec.rb +12 -0
  64. data/spec/models/mailbox_grant_list_spec.rb +1 -1
  65. data/spec/models/mailbox_grant_spec.rb +13 -1
  66. data/spec/models/mark_read_result_spec.rb +6 -0
  67. data/spec/models/simulated_inbound_spec.rb +18 -0
  68. data/spec/models/thread_classification_spec.rb +6 -0
  69. data/spec/models/{thread_message_body_all_of_body_spec.rb → thread_message_body_body_spec.rb} +6 -6
  70. data/spec/models/thread_message_body_spec.rb +5 -57
  71. data/spec/models/whoami_key_spec.rb +42 -0
  72. data/spec/models/whoami_spec.rb +8 -4
  73. data/spec/models/whoami_tenant_spec.rb +48 -0
  74. metadata +14 -6
@@ -0,0 +1,157 @@
1
+ =begin
2
+ #lockally control plane
3
+
4
+ #The lockally control plane lets integrators and direct customers manage everything except actual mail data flow (which uses standard JMAP / IMAP / SMTP-submission against the data plane endpoints). **Authentication.** All `/v1/*` endpoints require a Bearer API key in the `Authorization` header. Keys are formatted `lk_live_<8-char-prefix>_<32-char-secret>`, or `lk_test_<...>` for a test key. Create keys in the dashboard, or with `POST /v1/api-keys` using a key that holds `tenant:admin`. The key's plan is checked on every request, so a key stops working if the account moves to a plan without API access, and works again if it moves back. **Errors.** Failures return [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457) `application/problem+json` documents. **Scopes.** Each endpoint requires a specific scope on the presented key. Insufficient scope returns `403` with the required scope name in `detail`.
5
+
6
+ The version of the OpenAPI document: 0.1.0
7
+ Contact: support@lockally.com
8
+ Generated by: https://openapi-generator.tech
9
+ Generator version: 7.23.0
10
+
11
+ =end
12
+
13
+ require 'date'
14
+ require 'time'
15
+
16
+ module Lockally
17
+ # Present only when auth is api_key.
18
+ class WhoamiKey < ApiModelBase
19
+ attr_accessor :id
20
+
21
+ attr_accessor :label
22
+
23
+ # Attribute mapping from ruby-style variable name to JSON key.
24
+ def self.attribute_map
25
+ {
26
+ :'id' => :'id',
27
+ :'label' => :'label'
28
+ }
29
+ end
30
+
31
+ # Returns attribute mapping this model knows about
32
+ def self.acceptable_attribute_map
33
+ attribute_map
34
+ end
35
+
36
+ # Returns all the JSON keys this model knows about
37
+ def self.acceptable_attributes
38
+ acceptable_attribute_map.values
39
+ end
40
+
41
+ # Attribute type mapping.
42
+ def self.openapi_types
43
+ {
44
+ :'id' => :'String',
45
+ :'label' => :'String'
46
+ }
47
+ end
48
+
49
+ # List of attributes with nullable: true
50
+ def self.openapi_nullable
51
+ Set.new([
52
+ ])
53
+ end
54
+
55
+ # Initializes the object
56
+ # @param [Hash] attributes Model attributes in the form of hash
57
+ def initialize(attributes = {})
58
+ if (!attributes.is_a?(Hash))
59
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Lockally::WhoamiKey` initialize method"
60
+ end
61
+
62
+ # check to see if the attribute exists and convert string to symbol for hash key
63
+ acceptable_attribute_map = self.class.acceptable_attribute_map
64
+ attributes = attributes.each_with_object({}) { |(k, v), h|
65
+ if (!acceptable_attribute_map.key?(k.to_sym))
66
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Lockally::WhoamiKey`. Please check the name to make sure it's valid. List of attributes: " + acceptable_attribute_map.keys.inspect
67
+ end
68
+ h[k.to_sym] = v
69
+ }
70
+
71
+ if attributes.key?(:'id')
72
+ self.id = attributes[:'id']
73
+ end
74
+
75
+ if attributes.key?(:'label')
76
+ self.label = attributes[:'label']
77
+ end
78
+ end
79
+
80
+ # Show invalid properties with the reasons. Usually used together with valid?
81
+ # @return Array for valid properties with the reasons
82
+ def list_invalid_properties
83
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
84
+ invalid_properties = Array.new
85
+ invalid_properties
86
+ end
87
+
88
+ # Check to see if the all the properties in the model are valid
89
+ # @return true if the model is valid
90
+ def valid?
91
+ warn '[DEPRECATED] the `valid?` method is obsolete'
92
+ true
93
+ end
94
+
95
+ # Checks equality by comparing each attribute.
96
+ # @param [Object] Object to be compared
97
+ def ==(o)
98
+ return true if self.equal?(o)
99
+ self.class == o.class &&
100
+ id == o.id &&
101
+ label == o.label
102
+ end
103
+
104
+ # @see the `==` method
105
+ # @param [Object] Object to be compared
106
+ def eql?(o)
107
+ self == o
108
+ end
109
+
110
+ # Calculates hash code according to all attributes.
111
+ # @return [Integer] Hash code
112
+ def hash
113
+ [id, label].hash
114
+ end
115
+
116
+ # Builds the object from hash
117
+ # @param [Hash] attributes Model attributes in the form of hash
118
+ # @return [Object] Returns the model itself
119
+ def self.build_from_hash(attributes)
120
+ return nil unless attributes.is_a?(Hash)
121
+ attributes = attributes.transform_keys(&:to_sym)
122
+ transformed_hash = {}
123
+ openapi_types.each_pair do |key, type|
124
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
125
+ transformed_hash["#{key}"] = nil
126
+ elsif type =~ /\AArray<(.*)>/i
127
+ # check to ensure the input is an array given that the attribute
128
+ # is documented as an array but the input is not
129
+ if attributes[attribute_map[key]].is_a?(Array)
130
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
131
+ end
132
+ elsif !attributes[attribute_map[key]].nil?
133
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
134
+ end
135
+ end
136
+ new(transformed_hash)
137
+ end
138
+
139
+ # Returns the object in the form of hash
140
+ # @return [Hash] Returns the object in the form of hash
141
+ def to_hash
142
+ hash = {}
143
+ self.class.attribute_map.each_pair do |attr, param|
144
+ value = self.send(attr)
145
+ if value.nil?
146
+ is_nullable = self.class.openapi_nullable.include?(attr)
147
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
148
+ end
149
+
150
+ hash[param] = _to_hash(value)
151
+ end
152
+ hash
153
+ end
154
+
155
+ end
156
+
157
+ end
@@ -0,0 +1,166 @@
1
+ =begin
2
+ #lockally control plane
3
+
4
+ #The lockally control plane lets integrators and direct customers manage everything except actual mail data flow (which uses standard JMAP / IMAP / SMTP-submission against the data plane endpoints). **Authentication.** All `/v1/*` endpoints require a Bearer API key in the `Authorization` header. Keys are formatted `lk_live_<8-char-prefix>_<32-char-secret>`, or `lk_test_<...>` for a test key. Create keys in the dashboard, or with `POST /v1/api-keys` using a key that holds `tenant:admin`. The key's plan is checked on every request, so a key stops working if the account moves to a plan without API access, and works again if it moves back. **Errors.** Failures return [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457) `application/problem+json` documents. **Scopes.** Each endpoint requires a specific scope on the presented key. Insufficient scope returns `403` with the required scope name in `detail`.
5
+
6
+ The version of the OpenAPI document: 0.1.0
7
+ Contact: support@lockally.com
8
+ Generated by: https://openapi-generator.tech
9
+ Generator version: 7.23.0
10
+
11
+ =end
12
+
13
+ require 'date'
14
+ require 'time'
15
+
16
+ module Lockally
17
+ class WhoamiTenant < ApiModelBase
18
+ attr_accessor :slug
19
+
20
+ # What the account calls itself.
21
+ attr_accessor :name
22
+
23
+ attr_accessor :plan
24
+
25
+ # Attribute mapping from ruby-style variable name to JSON key.
26
+ def self.attribute_map
27
+ {
28
+ :'slug' => :'slug',
29
+ :'name' => :'name',
30
+ :'plan' => :'plan'
31
+ }
32
+ end
33
+
34
+ # Returns attribute mapping this model knows about
35
+ def self.acceptable_attribute_map
36
+ attribute_map
37
+ end
38
+
39
+ # Returns all the JSON keys this model knows about
40
+ def self.acceptable_attributes
41
+ acceptable_attribute_map.values
42
+ end
43
+
44
+ # Attribute type mapping.
45
+ def self.openapi_types
46
+ {
47
+ :'slug' => :'String',
48
+ :'name' => :'String',
49
+ :'plan' => :'String'
50
+ }
51
+ end
52
+
53
+ # List of attributes with nullable: true
54
+ def self.openapi_nullable
55
+ Set.new([
56
+ ])
57
+ end
58
+
59
+ # Initializes the object
60
+ # @param [Hash] attributes Model attributes in the form of hash
61
+ def initialize(attributes = {})
62
+ if (!attributes.is_a?(Hash))
63
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Lockally::WhoamiTenant` initialize method"
64
+ end
65
+
66
+ # check to see if the attribute exists and convert string to symbol for hash key
67
+ acceptable_attribute_map = self.class.acceptable_attribute_map
68
+ attributes = attributes.each_with_object({}) { |(k, v), h|
69
+ if (!acceptable_attribute_map.key?(k.to_sym))
70
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Lockally::WhoamiTenant`. Please check the name to make sure it's valid. List of attributes: " + acceptable_attribute_map.keys.inspect
71
+ end
72
+ h[k.to_sym] = v
73
+ }
74
+
75
+ if attributes.key?(:'slug')
76
+ self.slug = attributes[:'slug']
77
+ end
78
+
79
+ if attributes.key?(:'name')
80
+ self.name = attributes[:'name']
81
+ end
82
+
83
+ if attributes.key?(:'plan')
84
+ self.plan = attributes[:'plan']
85
+ end
86
+ end
87
+
88
+ # Show invalid properties with the reasons. Usually used together with valid?
89
+ # @return Array for valid properties with the reasons
90
+ def list_invalid_properties
91
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
92
+ invalid_properties = Array.new
93
+ invalid_properties
94
+ end
95
+
96
+ # Check to see if the all the properties in the model are valid
97
+ # @return true if the model is valid
98
+ def valid?
99
+ warn '[DEPRECATED] the `valid?` method is obsolete'
100
+ true
101
+ end
102
+
103
+ # Checks equality by comparing each attribute.
104
+ # @param [Object] Object to be compared
105
+ def ==(o)
106
+ return true if self.equal?(o)
107
+ self.class == o.class &&
108
+ slug == o.slug &&
109
+ name == o.name &&
110
+ plan == o.plan
111
+ end
112
+
113
+ # @see the `==` method
114
+ # @param [Object] Object to be compared
115
+ def eql?(o)
116
+ self == o
117
+ end
118
+
119
+ # Calculates hash code according to all attributes.
120
+ # @return [Integer] Hash code
121
+ def hash
122
+ [slug, name, plan].hash
123
+ end
124
+
125
+ # Builds the object from hash
126
+ # @param [Hash] attributes Model attributes in the form of hash
127
+ # @return [Object] Returns the model itself
128
+ def self.build_from_hash(attributes)
129
+ return nil unless attributes.is_a?(Hash)
130
+ attributes = attributes.transform_keys(&:to_sym)
131
+ transformed_hash = {}
132
+ openapi_types.each_pair do |key, type|
133
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
134
+ transformed_hash["#{key}"] = nil
135
+ elsif type =~ /\AArray<(.*)>/i
136
+ # check to ensure the input is an array given that the attribute
137
+ # is documented as an array but the input is not
138
+ if attributes[attribute_map[key]].is_a?(Array)
139
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
140
+ end
141
+ elsif !attributes[attribute_map[key]].nil?
142
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
143
+ end
144
+ end
145
+ new(transformed_hash)
146
+ end
147
+
148
+ # Returns the object in the form of hash
149
+ # @return [Hash] Returns the object in the form of hash
150
+ def to_hash
151
+ hash = {}
152
+ self.class.attribute_map.each_pair do |attr, param|
153
+ value = self.send(attr)
154
+ if value.nil?
155
+ is_nullable = self.class.openapi_nullable.include?(attr)
156
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
157
+ end
158
+
159
+ hash[param] = _to_hash(value)
160
+ end
161
+ hash
162
+ end
163
+
164
+ end
165
+
166
+ end
@@ -11,5 +11,5 @@ Generator version: 7.23.0
11
11
  =end
12
12
 
13
13
  module Lockally
14
- VERSION = '0.3.1'
14
+ VERSION = '0.3.3'
15
15
  end
data/lib/lockally.rb CHANGED
@@ -203,7 +203,7 @@ require 'lockally/models/thread_classification'
203
203
  require 'lockally/models/thread_list'
204
204
  require 'lockally/models/thread_message'
205
205
  require 'lockally/models/thread_message_body'
206
- require 'lockally/models/thread_message_body_all_of_body'
206
+ require 'lockally/models/thread_message_body_body'
207
207
  require 'lockally/models/thread_summary'
208
208
  require 'lockally/models/unit_bundle'
209
209
  require 'lockally/models/update_admin_request'
@@ -228,6 +228,8 @@ require 'lockally/models/vacation_params'
228
228
  require 'lockally/models/vacation_responder'
229
229
  require 'lockally/models/webhook'
230
230
  require 'lockally/models/whoami'
231
+ require 'lockally/models/whoami_key'
232
+ require 'lockally/models/whoami_tenant'
231
233
 
232
234
  # APIs
233
235
  require 'lockally/api/add_ons_api'
@@ -34,7 +34,7 @@ describe 'AdminApi' do
34
34
 
35
35
  # unit tests for admin_login
36
36
  # Tenant-admin email+password login
37
- # Exchanges an admin&#39;s email + password for a session token. The web console at &#x60;app.lockally.com&#x60; posts this on form submission and stores the returned token in an httpOnly cookie. **No enumeration leak.** Wrong-email and wrong-password both return the same 401 with title \&quot;Invalid credentials\&quot;. The argon2id verify runs even on lookup miss (well, structurally — the lookup fails fast but the response shape is constant) so timing leaks are bounded. Tokens are prefixed &#x60;adm_sess_&#x60; and valid for 7 days. Use as the &#x60;Authorization: Bearer&#x60; value on all subsequent calls.
37
+ # Exchanges an admin&#39;s email + password for a session token. The web console at &#x60;app.lockally.com&#x60; posts this on form submission and stores the returned token in an httpOnly cookie. **No enumeration leak.** Wrong-email and wrong-password both return the same 401 with title \&quot;Invalid credentials\&quot;. The argon2id verify runs even on lookup miss (well, structurally, the lookup fails fast but the response shape is constant) so timing leaks are bounded. Tokens are prefixed &#x60;adm_sess_&#x60; and valid for 7 days. Use as the &#x60;Authorization: Bearer&#x60; value on all subsequent calls.
38
38
  # @param admin_login_request
39
39
  # @param [Hash] opts the optional parameters
40
40
  # @return [AdminLogin200Response]
@@ -46,7 +46,7 @@ describe 'AdminApi' do
46
46
 
47
47
  # unit tests for admin_logout
48
48
  # Invalidate the current admin session
49
- # Deletes the session row from the database. Idempotent — calling logout on an already-invalid token returns 204 anyway.
49
+ # Deletes the session row from the database. Idempotent, calling logout on an already-invalid token returns 204 anyway.
50
50
  # @param [Hash] opts the optional parameters
51
51
  # @return [nil]
52
52
  describe 'admin_logout test' do
@@ -57,7 +57,7 @@ describe 'AdminApi' do
57
57
 
58
58
  # unit tests for get_current_admin
59
59
  # Get the current admin + tenant
60
- # Returns the admin profile + tenant for the session token presented in &#x60;Authorization: Bearer&#x60;. Used by the web console&#39;s layout load function to populate the sidebar. Returns 403 if called with an API key (lk_live_*) bearer — admin context only exists for session tokens.
60
+ # Returns the admin profile + tenant for the session token presented in &#x60;Authorization: Bearer&#x60;. Used by the web console&#39;s layout load function to populate the sidebar. Returns 403 if called with an API key (lk_live_*) bearer, admin context only exists for session tokens.
61
61
  # @param [Hash] opts the optional parameters
62
62
  # @return [GetCurrentAdmin200Response]
63
63
  describe 'get_current_admin test' do
@@ -68,7 +68,7 @@ describe 'AdminsApi' do
68
68
 
69
69
  # unit tests for update_admin
70
70
  # Update an admin
71
- # Supply at least one of &#x60;password&#x60;, &#x60;display_name&#x60;, &#x60;role&#x60;, &#x60;disabled&#x60;. **Safety rails.** A session bearer (adm_sess_*) cannot disable itself — use another admin or an API key (which bypasses the self-rail). Disabling the last active admin returns 409 to prevent orphaning the tenant from its console.
71
+ # Supply at least one of &#x60;password&#x60;, &#x60;display_name&#x60;, &#x60;role&#x60;, &#x60;disabled&#x60;. **Safety rails.** A session bearer (adm_sess_*) cannot disable itself, use another admin or an API key (which bypasses the self-rail). Disabling the last active admin returns 409 to prevent orphaning the tenant from its console.
72
72
  # @param id
73
73
  # @param update_admin_request
74
74
  # @param [Hash] opts the optional parameters
@@ -72,7 +72,7 @@ describe 'AgentsApi' do
72
72
 
73
73
  # unit tests for grant_api_key_mailbox
74
74
  # Grant a mailbox to a key
75
- # Body: {\&quot;mailbox\&quot;: \&quot;email or id\&quot;}. Refused (422) for mailboxes with agent access disabled or an active E2E encryption key — the server cannot read E2E mailboxes.
75
+ # Body: {\&quot;mailbox\&quot;: \&quot;email or id\&quot;}. Refused (422) for mailboxes with agent access disabled or an active E2E encryption key, the server cannot read E2E mailboxes.
76
76
  # @param key_id
77
77
  # @param [Hash] opts the optional parameters
78
78
  # @return [MailboxGrant]
@@ -146,7 +146,7 @@ describe 'AgentsApi' do
146
146
 
147
147
  # unit tests for reply_to_thread
148
148
  # Reply in-thread (agent stream)
149
- # The server builds In-Reply-To/References and defaults recipients + subject from the conversation — a minimal call is {\&quot;text\&quot;: \&quot;...\&quot;}. Guarded by the reply-loop detector (≥5 outbound/10min → 429 + agent.loop_detected). Idempotency-Key required.
149
+ # The server builds In-Reply-To/References and defaults recipients + subject from the conversation, a minimal call is {\&quot;text\&quot;: \&quot;...\&quot;}. Guarded by the reply-loop detector (≥5 outbound/10min → 429 + agent.loop_detected). Idempotency-Key required.
150
150
  # @param thread_id
151
151
  # @param idempotency_key
152
152
  # @param [Hash] opts the optional parameters
@@ -34,7 +34,7 @@ describe 'AiApi' do
34
34
 
35
35
  # unit tests for classify_thread
36
36
  # LLM-classify a thread
37
- # Returns {intent, urgency, summary, suggested_action} via the tenant&#39;s AI tier (BYOK or prepaid units — see /v1/ai-config). Cached per thread state: unchanged threads return the cache free; ?refresh&#x3D;true forces a re-run. A failed model call charges nothing. 402 when the AI tier is off.
37
+ # Returns {intent, urgency, summary, suggested_action} via the tenant&#39;s AI tier (BYOK or prepaid units, see /v1/ai-config). Cached per thread state: unchanged threads return the cache free; ?refresh&#x3D;true forces a re-run. A failed model call charges nothing. 402 when the AI tier is off.
38
38
  # @param thread_id
39
39
  # @param [Hash] opts the optional parameters
40
40
  # @option opts [Boolean] :refresh
@@ -46,7 +46,7 @@ describe 'AliasesApi' do
46
46
 
47
47
  # unit tests for delete_alias
48
48
  # Delete an alias
49
- # Hard-delete (no soft-delete window — aliases are cheap to recreate).
49
+ # Hard-delete (no soft-delete window, aliases are cheap to recreate).
50
50
  # @param address
51
51
  # @param [Hash] opts the optional parameters
52
52
  # @return [nil]
@@ -34,7 +34,7 @@ describe 'ApiKeysApi' do
34
34
 
35
35
  # unit tests for create_api_key
36
36
  # Create an API key
37
- # Provisions a fresh API key for the calling tenant. **The full &#x60;secret&#x60; is included in this response ONLY** — store it immediately. The cleartext secret is not recoverable from the argon2id hash kept server-side; rotate by creating a new key and revoking the old one.
37
+ # Provisions a fresh API key for the calling tenant. **The full &#x60;secret&#x60; is included in this response ONLY**, store it immediately. The cleartext secret is not recoverable from the argon2id hash kept server-side; rotate by creating a new key and revoking the old one.
38
38
  # @param create_api_key_request
39
39
  # @param [Hash] opts the optional parameters
40
40
  # @return [CreateApiKey201Response]
@@ -46,7 +46,7 @@ describe 'ApiKeysApi' do
46
46
 
47
47
  # unit tests for list_api_keys
48
48
  # List API keys
49
- # Returns all API keys (active and revoked) belonging to the calling tenant. The &#x60;secret&#x60; is **never** returned — only prefix + metadata.
49
+ # Returns all API keys (active and revoked) belonging to the calling tenant. The &#x60;secret&#x60; is **never** returned, only prefix + metadata.
50
50
  # @param [Hash] opts the optional parameters
51
51
  # @return [ListApiKeys200Response]
52
52
  describe 'list_api_keys test' do
@@ -57,7 +57,7 @@ describe 'ApiKeysApi' do
57
57
 
58
58
  # unit tests for revoke_api_key
59
59
  # Revoke an API key
60
- # Soft-deletes (sets &#x60;revoked_at&#x60;) on the named key. The row stays for audit purposes; the key no longer authenticates. You **cannot revoke the key currently being used** to make this call — that would lock you out. Use a different &#x60;tenant:admin&#x60; key.
60
+ # Soft-deletes (sets &#x60;revoked_at&#x60;) on the named key. The row stays for audit purposes; the key no longer authenticates. You **cannot revoke the key currently being used** to make this call, that would lock you out. Use a different &#x60;tenant:admin&#x60; key.
61
61
  # @param id
62
62
  # @param [Hash] opts the optional parameters
63
63
  # @return [nil]
@@ -34,7 +34,7 @@ describe 'DomainsApi' do
34
34
 
35
35
  # unit tests for create_domain
36
36
  # Register a domain
37
- # Registers a new domain for the calling tenant. Generates a DKIM keypair and verification token. Returns DNS instructions the tenant must publish under their own DNS (verification TXT, SPF include, DKIM TXT, MX records to &#x60;mx1&#x60;/&#x60;mx2.lockally.com&#x60;, DMARC seed). **Idempotent** — re-posting the same domain returns the existing record with the same DKIM keys and token (regenerating would break the tenant&#39;s published DNS). Returns 200 on idempotent hit, 201 on first create. Returns 409 if the domain is already claimed by a different tenant.
37
+ # Registers a new domain for the calling tenant. Generates a DKIM keypair and verification token. Returns DNS instructions the tenant must publish under their own DNS (verification TXT, SPF include, DKIM TXT, MX records to &#x60;mx1&#x60;/&#x60;mx2.lockally.com&#x60;, DMARC seed). **Idempotent**, re-posting the same domain returns the existing record with the same DKIM keys and token (regenerating would break the tenant&#39;s published DNS). Returns 200 on idempotent hit, 201 on first create. Returns 409 if the domain is already claimed by a different tenant.
38
38
  # @param create_domain_request
39
39
  # @param [Hash] opts the optional parameters
40
40
  # @return [Domain]
@@ -46,7 +46,7 @@ describe 'DomainsApi' do
46
46
 
47
47
  # unit tests for delete_domain
48
48
  # Delete a domain
49
- # Removes the domain registration. Refuses with 409 if any mailbox is still attached — delete the mailboxes first.
49
+ # Removes the domain registration. Refuses with 409 if any mailbox is still attached, delete the mailboxes first.
50
50
  # @param domain
51
51
  # @param [Hash] opts the optional parameters
52
52
  # @return [nil]
@@ -116,7 +116,7 @@ describe 'DomainsApi' do
116
116
 
117
117
  # unit tests for verify_domain
118
118
  # Force-poll DNS verification
119
- # Synchronously checks the &#x60;_lockally-verify.&lt;domain&gt;&#x60; TXT record against the stored verification token. Returns 200 either way: the returned &#x60;verified&#x60; boolean tells you whether DNS now confirms. Caller polls until &#x60;verified: true&#x60;. In v2 a background worker auto-polls and fires a &#x60;domain.verified&#x60; webhook.
119
+ # Synchronously checks the &#x60;_lockally-verify.&lt;domain&gt;&#x60; TXT record against the stored verification token. Returns 200 either way: the returned &#x60;verified&#x60; boolean tells you whether DNS now confirms. Caller polls until &#x60;verified: true&#x60;. A later version may have the platform auto-polls and fires a &#x60;domain.verified&#x60; webhook.
120
120
  # @param domain
121
121
  # @param [Hash] opts the optional parameters
122
122
  # @return [Domain]
@@ -46,7 +46,7 @@ describe 'MailboxesApi' do
46
46
 
47
47
  # unit tests for create_mailbox
48
48
  # Create a mailbox
49
- # Creates a mailbox on a tenant-verified domain. If &#x60;password&#x60; is omitted, lockally generates a 16-char password and returns it in the response — shown once. **Gate.** The mailbox&#39;s domain must already be registered AND verified for this tenant (via &#x60;/v1/domains&#x60; + &#x60;/v1/domains/{domain}/verify&#x60;). **Idempotent.** Re-posting the same email returns the existing mailbox UNTOUCHED — password is NOT regenerated. To change a password, use PATCH instead.
49
+ # Creates a mailbox on a tenant-verified domain. If &#x60;password&#x60; is omitted, lockally generates a 16-char password and returns it in the response, shown once. **Gate.** The mailbox&#39;s domain must already be registered AND verified for this tenant (via &#x60;/v1/domains&#x60; + &#x60;/v1/domains/{domain}/verify&#x60;). **Idempotent.** Re-posting the same email returns the existing mailbox UNTOUCHED, password is NOT regenerated. To change a password, use PATCH instead.
50
50
  # @param create_mailbox_request
51
51
  # @param [Hash] opts the optional parameters
52
52
  # @return [Mailbox]
@@ -70,7 +70,7 @@ describe 'MailboxesApi' do
70
70
 
71
71
  # unit tests for delete_vacation_responder
72
72
  # Remove the vacation responder
73
- # Idempotent — 204 whether or not a row existed.
73
+ # Idempotent, 204 whether or not a row existed.
74
74
  # @param email
75
75
  # @param [Hash] opts the optional parameters
76
76
  # @return [nil]
@@ -82,7 +82,7 @@ describe 'MailboxesApi' do
82
82
 
83
83
  # unit tests for download_mailbox_export
84
84
  # Download a previously-issued mailbox export
85
- # Public endpoint (no Authorization header). Validates the one-shot token from the URL, marks it used, and streams an mbox file. Second GET with the same token returns 404 — tokens are single-use.
85
+ # Public endpoint (no Authorization header). Validates the one-shot token from the URL, marks it used, and streams an mbox file. Second GET with the same token returns 404, tokens are single-use.
86
86
  # @param email
87
87
  # @param token
88
88
  # @param [Hash] opts the optional parameters
@@ -95,7 +95,7 @@ describe 'MailboxesApi' do
95
95
 
96
96
  # unit tests for export_mailbox
97
97
  # Request a mailbox export
98
- # Issues a one-shot \&quot;presigned\&quot; download URL for the mailbox&#39;s content in mbox format. The URL works without an Authorization header — the token in the query string is the authz. TTL is 5 minutes; the token is consumed on first GET. **v1 caveat:** the synthesized mbox only contains outbound mail (from &#x60;lockally.messages&#x60;). v2 swaps in Stalwart&#39;s export primitive for full inbox + folder structure + flags. The endpoint contract stays unchanged. **Scope changed:** this used to accept &#x60;mailboxes:read&#x60;. It takes any mailbox in the tenant and returns that mailbox&#39;s mail, so it now requires &#x60;tenant:admin&#x60;, matching &#x60;POST /v1/ediscovery/export&#x60;. A key scoped &#x60;mailboxes:read&#x60; gets 403 and has to be reissued; admin console sessions are unaffected.
98
+ # Issues a one-shot \&quot;presigned\&quot; download URL for the mailbox&#39;s content in mbox format. The URL works without an Authorization header, the token in the query string is the authz. TTL is 5 minutes; the token is consumed on first GET. **v1 caveat:** the synthesized mbox only contains outbound mail (sent mail only). A later version will cover received mail for full inbox + folder structure + flags. The endpoint contract stays unchanged. **Scope changed:** this used to accept &#x60;mailboxes:read&#x60;. It takes any mailbox in the tenant and returns that mailbox&#39;s mail, so it now requires &#x60;tenant:admin&#x60;, matching &#x60;POST /v1/ediscovery/export&#x60;. A key scoped &#x60;mailboxes:read&#x60; gets 403 and has to be reissued; admin console sessions are unaffected.
99
99
  # @param email
100
100
  # @param [Hash] opts the optional parameters
101
101
  # @return [ExportMailbox201Response]
@@ -130,7 +130,7 @@ describe 'MailboxesApi' do
130
130
 
131
131
  # unit tests for list_mailboxes
132
132
  # List mailboxes
133
- # Returns mailboxes under the calling tenant — active and soft-deleted. &#x60;?limit&#x3D;N&#x60; between 1 and 200 (default 50).
133
+ # Returns mailboxes under the calling tenant, active and soft-deleted. &#x60;?limit&#x3D;N&#x60; between 1 and 200 (default 50).
134
134
  # @param [Hash] opts the optional parameters
135
135
  # @option opts [Integer] :limit
136
136
  # @return [ListMailboxes200Response]
@@ -176,7 +176,7 @@ describe 'MailboxesApi' do
176
176
 
177
177
  # unit tests for set_vacation_responder
178
178
  # Set the vacation responder
179
- # Upsert — same endpoint creates or replaces the rule. Clears &#x60;synced_at&#x60;; the rule is staged on lockally until a sync worker pushes it to the mail server.
179
+ # Upsert, same endpoint creates or replaces the rule. Clears &#x60;synced_at&#x60;; the rule is staged until a later sync pushes it to the mail server.
180
180
  # @param email
181
181
  # @param set_vacation_responder_request
182
182
  # @param [Hash] opts the optional parameters
@@ -57,7 +57,7 @@ describe 'SendApi' do
57
57
 
58
58
  # unit tests for get_message_stats
59
59
  # Aggregate delivery stats
60
- # Counts by delivery outcome (delivered/bounced/deferred/complaint) plus rates over a window, from the delivery-event store. Privacy-first: this reflects what receiving servers reported, NOT whether a human opened the mail — Lockally does no open/click tracking.
60
+ # Counts by delivery outcome (delivered/bounced/deferred/complaint) plus rates over a window, from the delivery-event store. Privacy-first: this reflects what receiving servers reported, NOT whether a human opened the mail, Lockally does no open/click tracking.
61
61
  # @param [Hash] opts the optional parameters
62
62
  # @option opts [Time] :from Window start (default 7 days ago).
63
63
  # @option opts [Time] :to Window end (default now).
@@ -71,7 +71,7 @@ describe 'SendApi' do
71
71
 
72
72
  # unit tests for list_messages
73
73
  # List outbound messages
74
- # Returns recent outbound messages for the calling tenant, sorted newest first. Backs the send-status pill in the SvelteKit /sends view and the outbound search box.
74
+ # Returns recent outbound messages for the calling tenant, sorted newest first.
75
75
  # @param [Hash] opts the optional parameters
76
76
  # @option opts [String] :status
77
77
  # @option opts [String] :sender Exact match against the &#x60;from&#x60; mailbox.
@@ -88,7 +88,7 @@ describe 'SendApi' do
88
88
 
89
89
  # unit tests for send_email
90
90
  # Send an email
91
- # Submits an email for delivery via lockally. Returns 202 immediately once the message is accepted into lockally&#39;s queue; the actual SMTP submission to the recipient is async. Track delivery via &#x60;GET /v1/messages/{id}&#x60; or webhook subscriptions for &#x60;delivery.delivered&#x60; / &#x60;delivery.bounced&#x60; / &#x60;delivery.complaint&#x60;. **Idempotency-Key required.** Per design L7 — any unique string per send, 24-hour dedupe window. Repeated calls with the same key return byte-exact the original response and do NOT create a duplicate message. **Sender authorisation.** &#x60;from&#x60; must be an address the calling tenant owns on a verified domain. A mailbox always qualifies. On business and combined accounts an **alias** qualifies too, so a send-only address such as &#x60;no-reply@&#x60; need not be a billed seat. An alias on an unverified domain, or one belonging to another account, is refused with &#x60;403&#x60;. A catch-all creates no aliases and so grants no sending rights. **Rate cap.** Per-tenant &#x60;rate_cap_per_min&#x60; (returned on &#x60;/v1/tenant&#x60;) is enforced — 429 with &#x60;Retry-After: 60&#x60; once tripped. **Recipient warning.** Over 25 total recipients (To+Cc+Bcc) sets a &#x60;warning&#x60; field in the response — large fan-outs queue noticeably at scale. Hard cap is 100/send. **Not every success is a 202.** Check the status code, not just the body. A &#x60;200&#x60; means nothing was queued: either every recipient was already suppressed, or the call used a test key and the send was simulated. Both are successes, and neither produces a real delivery. See the &#x60;200&#x60; response below. **Warm-up headers.** While the platform is in its outbound warm-up ramp, accepted sends carry &#x60;X-Warmup-Day&#x60;, &#x60;X-Warmup-Daily-Cap&#x60; and &#x60;X-Warmup-Used-Today&#x60;. They describe a platform-wide cap shared by every tenant, not your own allowance, and they disappear once the ramp finishes. Hitting the cap returns 429.
91
+ # Submits an email for delivery via lockally. Returns 202 immediately once the message is accepted into lockally&#39;s queue; the actual SMTP submission to the recipient is async. Track delivery via &#x60;GET /v1/messages/{id}&#x60; or webhook subscriptions for &#x60;delivery.delivered&#x60; / &#x60;delivery.bounced&#x60; / &#x60;delivery.complaint&#x60;. **Idempotency-Key required.** Any unique string per send, 24-hour dedupe window. Repeated calls with the same key return byte-exact the original response and do NOT create a duplicate message. **Sender authorisation.** &#x60;from&#x60; must be an address the calling tenant owns on a verified domain. A mailbox always qualifies. On business and combined accounts an **alias** qualifies too, so a send-only address such as &#x60;no-reply@&#x60; need not be a billed seat. An alias on an unverified domain, or one belonging to another account, is refused with &#x60;403&#x60;. A catch-all creates no aliases and so grants no sending rights. **Rate cap.** Per-tenant &#x60;rate_cap_per_min&#x60; (returned on &#x60;/v1/tenant&#x60;) is enforced, 429 with &#x60;Retry-After: 60&#x60; once tripped. **Recipient warning.** Over 25 total recipients (To+Cc+Bcc) sets a &#x60;warning&#x60; field in the response, large fan-outs queue noticeably at scale. Hard cap is 100/send. **Not every success is a 202.** Check the status code, not just the body. A &#x60;200&#x60; means nothing was queued: either every recipient was already suppressed, or the call used a test key and the send was simulated. Both are successes, and neither produces a real delivery. See the &#x60;200&#x60; response below. **Warm-up headers.** While the platform is in its outbound warm-up ramp, accepted sends carry &#x60;X-Warmup-Day&#x60;, &#x60;X-Warmup-Daily-Cap&#x60; and &#x60;X-Warmup-Used-Today&#x60;. They describe a platform-wide cap shared by every tenant, not your own allowance, and they disappear once the ramp finishes. Hitting the cap returns 429.
92
92
  # @param idempotency_key
93
93
  # @param send_email_request
94
94
  # @param [Hash] opts the optional parameters
@@ -101,7 +101,7 @@ describe 'SendApi' do
101
101
 
102
102
  # unit tests for send_email_batch
103
103
  # Send a batch of emails
104
- # Sends up to 500 messages in one call. Each is validated and enqueued independently — a bad message fails only its own slot (partial success, HTTP 200). One &#x60;Idempotency-Key&#x60; header covers the batch; per-message keys are derived as &#x60;&lt;key&gt;:&lt;index&gt;&#x60;.
104
+ # Sends up to 500 messages in one call. Each is validated and enqueued independently, a bad message fails only its own slot (partial success, HTTP 200). One &#x60;Idempotency-Key&#x60; header covers the batch; per-message keys are derived as &#x60;&lt;key&gt;:&lt;index&gt;&#x60;.
105
105
  # @param idempotency_key
106
106
  # @param send_email_batch_request
107
107
  # @param [Hash] opts the optional parameters
@@ -45,7 +45,7 @@ describe 'TenantApi' do
45
45
 
46
46
  # unit tests for get_usage
47
47
  # Usage snapshot
48
- # Returns the tenant&#39;s current usage + cap consumption. Designed for poll-based alerting on the integrator side (e.g. \&quot;warn when daily quota is 80% used\&quot;). Refreshed live from Postgres — there is no cache, so callers should poll at most once per minute.
48
+ # Returns the tenant&#39;s current usage + cap consumption. Designed for poll-based alerting on the integrator side (e.g. \&quot;warn when daily quota is 80% used\&quot;). Computed live on request, so there is no cache, so callers should poll at most once per minute.
49
49
  # @param [Hash] opts the optional parameters
50
50
  # @return [GetUsage200Response]
51
51
  describe 'get_usage test' do
@@ -34,7 +34,7 @@ describe 'TestApi' do
34
34
 
35
35
  # unit tests for simulate_inbound_email
36
36
  # Simulate an inbound email (test keys only)
37
- # Runs a synthetic message through the REAL indexing pipeline — thread adoption, deterministic extraction (incl. injection_risk), and the message.received webhook — so the whole agent loop is testable without a real domain or MTA. Requires an lk_test_* key (create with {\&quot;test\&quot;: true} on POST /v1/api-keys). Body: {mailbox, from, subject, text, in_reply_to?, references?}.
37
+ # Runs a synthetic message through the REAL indexing pipeline, thread adoption, deterministic extraction (incl. injection_risk), and the message.received webhook, so the whole agent loop is testable without a real domain or MTA. Requires an lk_test_* key (create with {\&quot;test\&quot;: true} on POST /v1/api-keys). Body: {mailbox, from, subject, text, in_reply_to?, references?}.
38
38
  # @param [Hash] opts the optional parameters
39
39
  # @return [SimulatedInbound]
40
40
  describe 'simulate_inbound_email test' do
@@ -34,7 +34,7 @@ describe 'WebhooksApi' do
34
34
 
35
35
  # unit tests for create_webhook
36
36
  # Create a webhook
37
- # Subscribes a URL to one or more event types. Returns the &#x60;signing_secret&#x60; ONCE in the response — store it immediately. The dispatcher signs every outbound POST per design L3: X-Lockally-Signature: t&#x3D;&lt;unix&gt;,v1&#x3D;&lt;hex(hmac_sha256(secret, t + \&quot;.\&quot; + body))&gt; Verify on your end using HMAC-SHA256 with a 5-minute timestamp window (replay protection). A reference verifier ships in [internal/webhook](https://github.com/ucheigwedinma/lockally/blob/main/internal/webhook/sign.go). Event names: see the [event catalogue](https://github.com/ucheigwedinma/lockally/blob/main/docs/v1-design.md#64-webhook-event-catalogue-v1).
37
+ # Subscribes a URL to one or more event types. Returns the &#x60;signing_secret&#x60; ONCE in the response, store it immediately. Every outbound POST is signed: X-Lockally-Signature: t&#x3D;&lt;unix&gt;,v1&#x3D;&lt;hex(hmac_sha256(secret, t + \&quot;.\&quot; + body))&gt; Verify on your end using HMAC-SHA256 with a 5-minute timestamp window (replay protection). A reference verifier ships in [Signature verification](https://developers.lockally.com/webhooks/verification/). Event names: see the [event catalogue](https://developers.lockally.com/webhooks/events/).
38
38
  # @param create_webhook_request
39
39
  # @param [Hash] opts the optional parameters
40
40
  # @return [Webhook]
@@ -58,7 +58,7 @@ describe 'WebhooksApi' do
58
58
 
59
59
  # unit tests for list_webhooks
60
60
  # List webhooks
61
- # Returns the calling tenant&#39;s webhook subscriptions. Never returns the signing secret — only metadata.
61
+ # Returns the calling tenant&#39;s webhook subscriptions. Never returns the signing secret, only metadata.
62
62
  # @param [Hash] opts the optional parameters
63
63
  # @return [ListWebhooks200Response]
64
64
  describe 'list_webhooks test' do
@@ -69,7 +69,7 @@ describe 'WebhooksApi' do
69
69
 
70
70
  # unit tests for update_webhook
71
71
  # Update a webhook
72
- # Supply at least one of &#x60;url&#x60;, &#x60;events&#x60;, &#x60;paused&#x60;. Setting &#x60;paused&#x60; to &#x60;false&#x60; ALSO resets &#x60;consecutive_failures&#x60; to 0 — re-arms the 50-failure auto-pause counter.
72
+ # Supply at least one of &#x60;url&#x60;, &#x60;events&#x60;, &#x60;paused&#x60;. Setting &#x60;paused&#x60; to &#x60;false&#x60; ALSO resets &#x60;consecutive_failures&#x60; to 0, re-arms the 50-failure auto-pause counter.
73
73
  # @param id
74
74
  # @param update_webhook_request
75
75
  # @param [Hash] opts the optional parameters