truelist 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4cc95465750e1a4ac521ef820c07005f72cfacb9f02a4970aefd2b64aace82ca
4
+ data.tar.gz: 8679e804ef330c865a60ffaf0a02ffa6a437cb8854f36b8731dd666ec2218381
5
+ SHA512:
6
+ metadata.gz: b3fd1de9cde0aa2f490b46e583ef5dfde91359afe658d8374441a44f7edc500a6212ae7acfa4b731829090cc158c62ca5a851032ccf1ebcf1c80ca779fbddd25
7
+ data.tar.gz: a667a27d4f64fb1715aedcc97fc993d9feafca53c22ad0b88efd6082acb06f4b7c6795f524d0011db4a5870d665f4640d44037c8e8712c0cc926ce6fe11ee778
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Truelist
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,288 @@
1
+ # truelist
2
+
3
+ [![Free tier](https://img.shields.io/badge/free_plan-100_validations-4A7C59?style=flat-square)](https://truelist.io/pricing)
4
+ Ruby SDK for [Truelist.io](https://truelist.io) email validation.
5
+
6
+ [![Gem Version](https://badge.fury.io/rb/truelist.svg)](https://badge.fury.io/rb/truelist)
7
+ [![CI](https://github.com/Truelist-io-Email-Validation/truelist-ruby/actions/workflows/ci.yml/badge.svg)](https://github.com/Truelist-io-Email-Validation/truelist-ruby/actions/workflows/ci.yml)
8
+
9
+ Verify email deliverability with a pure Ruby client. Zero runtime dependencies. Works anywhere Ruby runs -- no Rails required.
10
+
11
+ > **Start free** — 100 validations + 10 enhanced credits, no credit card required.
12
+ > [Get your API key →](https://app.truelist.io/signup?utm_source=github&utm_medium=readme&utm_campaign=free-plan&utm_content=truelist-ruby)
13
+
14
+ ## Installation
15
+
16
+ Add to your Gemfile:
17
+
18
+ ```ruby
19
+ gem "truelist"
20
+ ```
21
+
22
+ Then run:
23
+
24
+ ```bash
25
+ bundle install
26
+ ```
27
+
28
+ Or install directly:
29
+
30
+ ```bash
31
+ gem install truelist
32
+ ```
33
+
34
+ ## Quick Start
35
+
36
+ ```ruby
37
+ require "truelist"
38
+
39
+ # Set your API key (or use TRUELIST_API_KEY env var)
40
+ Truelist.configure do |config|
41
+ config.api_key = "your-api-key"
42
+ end
43
+
44
+ # Validate an email
45
+ result = Truelist.validate("user@example.com")
46
+ result.valid? # => true
47
+ result.state # => "ok"
48
+ ```
49
+
50
+ ## Client Usage
51
+
52
+ ### Validate an email
53
+
54
+ ```ruby
55
+ client = Truelist::Client.new(api_key: "your-api-key")
56
+
57
+ result = client.validate("user@example.com")
58
+ result.state # => "ok"
59
+ result.sub_state # => "email_ok"
60
+ result.valid? # => true
61
+ result.domain # => "example.com"
62
+ result.verified_at # => "2026-02-21T10:00:00.000Z"
63
+ ```
64
+
65
+ ### Account info
66
+
67
+ ```ruby
68
+ account = client.account
69
+ account.email # => "you@company.com"
70
+ account.name # => "Team Lead"
71
+ account.payment_plan # => "pro"
72
+ account.admin? # => true
73
+ ```
74
+
75
+ The `account` method respects `raise_on_error`. When disabled (default), transient errors (429, 5xx, timeouts) return `nil` instead of raising. Authentication errors (401) always raise regardless of this setting.
76
+
77
+ ### Shortcut methods
78
+
79
+ Read `TRUELIST_API_KEY` from your environment automatically:
80
+
81
+ ```ruby
82
+ result = Truelist.validate("user@example.com")
83
+ ```
84
+
85
+ ## Configuration
86
+
87
+ ```ruby
88
+ Truelist.configure do |config|
89
+ # Your Truelist API key (required).
90
+ # Defaults to ENV["TRUELIST_API_KEY"].
91
+ config.api_key = ENV["TRUELIST_API_KEY"]
92
+
93
+ # API base URL. Change only for testing or proxying.
94
+ config.base_url = "https://api.truelist.io"
95
+
96
+ # Request timeout in seconds.
97
+ config.timeout = 10
98
+
99
+ # Max retry attempts on 429/5xx errors.
100
+ config.max_retries = 2
101
+
102
+ # When true, raises Truelist::Error on API failures.
103
+ # When false (default), returns an "unknown" result on transient errors,
104
+ # allowing your code to handle failures gracefully.
105
+ config.raise_on_error = false
106
+ end
107
+ ```
108
+
109
+ You can also pass configuration per-client:
110
+
111
+ ```ruby
112
+ client = Truelist::Client.new(
113
+ api_key: "different-key",
114
+ base_url: "https://custom.api.com",
115
+ timeout: 30,
116
+ max_retries: 5
117
+ )
118
+ ```
119
+
120
+ ## Error Handling
121
+
122
+ By default, transient errors (timeouts, rate limits, server errors) return a `Result` with `error?: true` and `state: "unknown"`. This prevents your application from breaking when the API is unreachable.
123
+
124
+ **Authentication errors (401) always raise**, regardless of the `raise_on_error` setting.
125
+
126
+ To raise exceptions on all errors:
127
+
128
+ ```ruby
129
+ Truelist.configure do |config|
130
+ config.raise_on_error = true
131
+ end
132
+ ```
133
+
134
+ Exception classes:
135
+
136
+ - `Truelist::Error` -- base error class
137
+ - `Truelist::AuthenticationError` -- invalid API key (401)
138
+ - `Truelist::RateLimitError` -- rate limit exceeded (429)
139
+ - `Truelist::ApiError` -- unexpected API responses (includes `status` and `body` attributes)
140
+
141
+ ## Retries
142
+
143
+ The client automatically retries on 429 (rate limit) and 5xx (server error) responses with exponential backoff. Configure with `max_retries` (default: 2).
144
+
145
+ ```ruby
146
+ Truelist.configure do |config|
147
+ config.max_retries = 3 # retry up to 3 times
148
+ end
149
+ ```
150
+
151
+ Set to `0` to disable retries.
152
+
153
+ ## Result Object
154
+
155
+ The `Truelist::Result` is a frozen data object with the following attributes:
156
+
157
+ | Attribute | Type | Description |
158
+ |-----------|------|-------------|
159
+ | `email` | String | The email that was validated |
160
+ | `state` | String | `"ok"`, `"email_invalid"`, `"accept_all"`, or `"unknown"` |
161
+ | `sub_state` | String | Detailed sub-state (see below) |
162
+ | `suggestion` | String/nil | Suggested correction, if available |
163
+ | `domain` | String/nil | Domain of the email address |
164
+ | `canonical` | String/nil | Canonical part of the email |
165
+ | `mx_record` | String/nil | MX record for the domain |
166
+ | `first_name` | String/nil | First name associated with the email |
167
+ | `last_name` | String/nil | Last name associated with the email |
168
+ | `verified_at` | String/nil | Timestamp of verification |
169
+ | `error` | Boolean | Whether an API error occurred |
170
+
171
+ ### Predicates
172
+
173
+ | Method | Returns true when |
174
+ |--------|-------------------|
175
+ | `valid?` | State is `"ok"` |
176
+ | `valid?(allow_risky: true)` | State is `"ok"` or `"accept_all"` |
177
+ | `deliverable?` | State is `"ok"` or `"accept_all"` (alias for `valid?(allow_risky: true)`) |
178
+ | `deliverable?(allow_risky: false)` | State is `"ok"` only |
179
+ | `invalid?` | State is `"email_invalid"` |
180
+ | `accept_all?` | State is `"accept_all"` |
181
+ | `unknown?` | State is `"unknown"` |
182
+ | `disposable?` | Sub-state is `"is_disposable"` |
183
+ | `role?` | Sub-state is `"is_role"` |
184
+ | `error?` | An API error occurred |
185
+
186
+ ### Sub-states
187
+
188
+ | Sub-state | Meaning |
189
+ |-----------|---------|
190
+ | `email_ok` | Email is valid and deliverable |
191
+ | `is_disposable` | Disposable/temporary email |
192
+ | `is_role` | Role-based address (info@, admin@) |
193
+ | `failed_smtp_check` | SMTP check failed |
194
+ | `unknown_error` | Could not determine status |
195
+
196
+ ## Account Info Object
197
+
198
+ The `Truelist::AccountInfo` is a frozen data object:
199
+
200
+ | Attribute | Type | Description |
201
+ |-----------|------|-------------|
202
+ | `email` | String | Account email |
203
+ | `name` | String | Account holder name |
204
+ | `uuid` | String | Account UUID |
205
+ | `time_zone` | String | Account time zone |
206
+ | `is_admin_role` | Boolean | Whether user is admin |
207
+ | `payment_plan` | String | Current payment plan |
208
+
209
+ ### Predicates
210
+
211
+ | Method | Returns true when |
212
+ |--------|-------------------|
213
+ | `admin?` | User has admin role |
214
+
215
+ ## For Rails Users
216
+
217
+ If you're using Rails, check out [truelist-rails](https://github.com/Truelist-io-Email-Validation/truelist-rails) which provides ActiveModel validators on top of this gem:
218
+
219
+ ```ruby
220
+ # Gemfile
221
+ gem "truelist-rails"
222
+
223
+ # app/models/user.rb
224
+ validates :email, deliverable: true
225
+ ```
226
+
227
+ ## Testing
228
+
229
+ Stub the API in your tests with WebMock:
230
+
231
+ ```ruby
232
+ require "webmock/rspec"
233
+
234
+ RSpec.configure do |config|
235
+ config.before do
236
+ stub_request(:post, %r{https://api\.truelist\.io/api/v1/verify_inline})
237
+ .to_return(
238
+ status: 200,
239
+ body: {
240
+ emails: [{
241
+ address: "user@example.com",
242
+ domain: "example.com",
243
+ canonical: "user",
244
+ mx_record: nil,
245
+ first_name: nil,
246
+ last_name: nil,
247
+ email_state: "ok",
248
+ email_sub_state: "email_ok",
249
+ verified_at: "2026-02-21T10:00:00.000Z",
250
+ did_you_mean: nil
251
+ }]
252
+ }.to_json,
253
+ headers: { "Content-Type" => "application/json" }
254
+ )
255
+ end
256
+ end
257
+ ```
258
+
259
+ Or stub at the client level:
260
+
261
+ ```ruby
262
+ allow(Truelist::Client).to receive(:new).and_return(
263
+ instance_double(Truelist::Client, validate: Truelist::Result.new(email: "user@example.com", state: "ok"))
264
+ )
265
+ ```
266
+
267
+ ## Requirements
268
+
269
+ - Ruby >= 3.0
270
+ - No runtime dependencies
271
+
272
+ ## Development
273
+
274
+ ```bash
275
+ git clone https://github.com/Truelist-io-Email-Validation/truelist-ruby.git
276
+ cd truelist-ruby
277
+ bundle install
278
+ bundle exec rspec
279
+ bundle exec rubocop
280
+ ```
281
+
282
+
283
+ ## Getting Started
284
+
285
+ Sign up for a [free Truelist account](https://app.truelist.io/signup?utm_source=github&utm_medium=readme&utm_campaign=free-plan&utm_content=truelist-ruby) to get your API key. The free plan includes 100 validations and 10 enhanced credits — no credit card required.
286
+ ## License
287
+
288
+ Released under the [MIT License](LICENSE).
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Truelist
4
+ class AccountInfo
5
+ attr_reader :email, :name, :uuid, :time_zone, :is_admin_role, :payment_plan
6
+
7
+ def initialize(email:, name:, uuid:, time_zone:, is_admin_role:, payment_plan:)
8
+ @email = email
9
+ @name = name
10
+ @uuid = uuid
11
+ @time_zone = time_zone
12
+ @is_admin_role = is_admin_role
13
+ @payment_plan = payment_plan
14
+ freeze
15
+ end
16
+
17
+ def admin?
18
+ @is_admin_role
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,180 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'uri'
5
+ require 'json'
6
+
7
+ module Truelist
8
+ class Client
9
+ def initialize(api_key: nil, **options)
10
+ @api_key = api_key
11
+ @base_url = options[:base_url]
12
+ @timeout = options[:timeout]
13
+ @max_retries = options[:max_retries]
14
+ @raise_on_error = options[:raise_on_error]
15
+ end
16
+
17
+ def validate(email)
18
+ uri = URI("#{base_url}/api/v1/verify_inline?email=#{URI.encode_www_form_component(email)}")
19
+
20
+ response = request_with_retries(:post, uri)
21
+ parse_validation_response(email, response)
22
+ rescue Truelist::AuthenticationError
23
+ raise
24
+ rescue StandardError => e
25
+ handle_error(email, e)
26
+ end
27
+
28
+ def account
29
+ uri = URI("#{base_url}/me")
30
+
31
+ response = request_with_retries(:get, uri)
32
+ parse_account_response(response)
33
+ rescue Truelist::AuthenticationError
34
+ raise
35
+ rescue StandardError
36
+ raise if raise_on_error?
37
+
38
+ nil
39
+ end
40
+
41
+ private
42
+
43
+ def config = Truelist.configuration
44
+ def api_key = @api_key || config.api_key!
45
+ def base_url = @base_url || config.base_url
46
+ def timeout = @timeout || config.timeout
47
+ def max_retries = @max_retries || config.max_retries
48
+
49
+ def raise_on_error?
50
+ return @raise_on_error unless @raise_on_error.nil?
51
+
52
+ config.raise_on_error
53
+ end
54
+
55
+ def request_with_retries(method, uri, auth_key: nil)
56
+ retries = 0
57
+ key = auth_key || api_key
58
+
59
+ loop do
60
+ response = perform_request(method, uri, auth_key: key)
61
+ check_authentication!(response)
62
+
63
+ return response if response.code.to_i < 429 || retries >= max_retries
64
+
65
+ if retryable_status?(response.code.to_i)
66
+ retries += 1
67
+ sleep(backoff_delay(retries))
68
+ next
69
+ end
70
+
71
+ return response
72
+ end
73
+ end
74
+
75
+ def check_authentication!(response)
76
+ return unless response.code.to_i == 401
77
+
78
+ raise Truelist::AuthenticationError, 'Invalid API key. Check your Truelist API key configuration.'
79
+ end
80
+
81
+ def retryable_status?(status)
82
+ status == 429 || status >= 500
83
+ end
84
+
85
+ def backoff_delay(retry_count)
86
+ (2**retry_count) * 0.1
87
+ end
88
+
89
+ def perform_request(method, uri, auth_key: nil)
90
+ http = build_http(uri)
91
+
92
+ request = build_request(method, uri, auth_key: auth_key || api_key)
93
+ http.request(request)
94
+ end
95
+
96
+ def build_http(uri)
97
+ http = Net::HTTP.new(uri.host, uri.port)
98
+ http.use_ssl = uri.scheme == 'https'
99
+ http.open_timeout = timeout
100
+ http.read_timeout = timeout
101
+ http
102
+ end
103
+
104
+ def build_request(method, uri, auth_key: nil)
105
+ request = case method
106
+ when :get then Net::HTTP::Get.new(uri)
107
+ when :post then Net::HTTP::Post.new(uri)
108
+ end
109
+
110
+ request['Authorization'] = "Bearer #{auth_key || api_key}"
111
+ request['Content-Type'] = 'application/json'
112
+ request['Accept'] = 'application/json'
113
+ request['User-Agent'] = "truelist-ruby/#{Truelist::VERSION}"
114
+
115
+ request
116
+ end
117
+
118
+ def parse_validation_response(email, response)
119
+ status = response.code.to_i
120
+
121
+ case status
122
+ when 200
123
+ parse_success(email, response.body)
124
+ when 429
125
+ handle_error(email, Truelist::RateLimitError.new('Rate limit exceeded'))
126
+ else
127
+ handle_error(email, Truelist::ApiError.new("API returned #{status}: #{response.body}",
128
+ status: status, body: response.body))
129
+ end
130
+ end
131
+
132
+ def parse_success(email_input, body)
133
+ data = JSON.parse(body)
134
+ email_data = data['emails']&.first || {}
135
+
136
+ Result.new(
137
+ email: email_data['address'] || email_input,
138
+ state: email_data['email_state'] || 'unknown',
139
+ sub_state: email_data['email_sub_state'],
140
+ suggestion: email_data['did_you_mean'],
141
+ domain: email_data['domain'],
142
+ canonical: email_data['canonical'],
143
+ mx_record: email_data['mx_record'],
144
+ first_name: email_data['first_name'],
145
+ last_name: email_data['last_name'],
146
+ verified_at: email_data['verified_at']
147
+ )
148
+ rescue JSON::ParserError => e
149
+ handle_error(email_input, e)
150
+ end
151
+
152
+ def parse_account_response(response)
153
+ status = response.code.to_i
154
+
155
+ case status
156
+ when 200
157
+ data = JSON.parse(response.body)
158
+ AccountInfo.new(
159
+ email: data['email'],
160
+ name: data['name'],
161
+ uuid: data['uuid'],
162
+ time_zone: data['time_zone'],
163
+ is_admin_role: data['is_admin_role'],
164
+ payment_plan: data.dig('account', 'payment_plan')
165
+ )
166
+ when 429
167
+ raise Truelist::RateLimitError, 'Rate limit exceeded'
168
+ else
169
+ raise Truelist::ApiError.new("API returned #{status}: #{response.body}",
170
+ status: status, body: response.body)
171
+ end
172
+ end
173
+
174
+ def handle_error(email, error)
175
+ raise error if raise_on_error?
176
+
177
+ Result.new(email: email, state: 'unknown', error: true)
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Truelist
4
+ class Configuration
5
+ attr_accessor :api_key, :base_url, :timeout, :max_retries, :raise_on_error
6
+
7
+ def initialize
8
+ @api_key = ENV.fetch('TRUELIST_API_KEY', nil)
9
+ @base_url = 'https://api.truelist.io'
10
+ @timeout = 10
11
+ @max_retries = 2
12
+ @raise_on_error = false
13
+ end
14
+
15
+ def api_key!
16
+ api_key || raise(Truelist::AuthenticationError,
17
+ 'Truelist API key is not configured. Set TRUELIST_API_KEY or use Truelist.configure.')
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Truelist
4
+ class Error < StandardError; end
5
+
6
+ class AuthenticationError < Error; end
7
+
8
+ class RateLimitError < Error; end
9
+
10
+ class ApiError < Error
11
+ attr_reader :status, :body
12
+
13
+ def initialize(message = nil, status: nil, body: nil)
14
+ @status = status
15
+ @body = body
16
+ super(message)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Truelist
4
+ class Result
5
+ attr_reader :email, :state, :sub_state, :suggestion, :domain, :canonical, :mx_record,
6
+ :first_name, :last_name, :verified_at, :error
7
+
8
+ def initialize(email:, state:, sub_state: nil, suggestion: nil, domain: nil, canonical: nil, mx_record: nil,
9
+ first_name: nil, last_name: nil, verified_at: nil, error: false)
10
+ @email = email
11
+ @state = state.to_s
12
+ @sub_state = sub_state&.to_s
13
+ @suggestion = suggestion
14
+ @domain = domain
15
+ @canonical = canonical
16
+ @mx_record = mx_record
17
+ @first_name = first_name
18
+ @last_name = last_name
19
+ @verified_at = verified_at
20
+ @error = error
21
+ freeze
22
+ end
23
+
24
+ def valid?(allow_risky: false)
25
+ return %w[ok accept_all].include?(state) if allow_risky
26
+
27
+ state == 'ok'
28
+ end
29
+
30
+ def deliverable?(allow_risky: true)
31
+ valid?(allow_risky: allow_risky)
32
+ end
33
+
34
+ def invalid?
35
+ state == 'email_invalid'
36
+ end
37
+
38
+ def accept_all?
39
+ state == 'accept_all'
40
+ end
41
+
42
+ def unknown?
43
+ state == 'unknown'
44
+ end
45
+
46
+ def disposable?
47
+ sub_state == 'is_disposable'
48
+ end
49
+
50
+ def role?
51
+ sub_state == 'is_role'
52
+ end
53
+
54
+ def error?
55
+ @error
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Truelist
4
+ VERSION = '0.2.0'
5
+ end
data/lib/truelist.rb ADDED
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'truelist/version'
4
+ require_relative 'truelist/errors'
5
+ require_relative 'truelist/configuration'
6
+ require_relative 'truelist/result'
7
+ require_relative 'truelist/account_info'
8
+ require_relative 'truelist/client'
9
+
10
+ module Truelist
11
+ class << self
12
+ def configuration
13
+ @configuration ||= Configuration.new
14
+ end
15
+
16
+ def configure
17
+ yield(configuration)
18
+ end
19
+
20
+ def reset_configuration!
21
+ @configuration = Configuration.new
22
+ end
23
+
24
+ def validate(email)
25
+ Client.new.validate(email)
26
+ end
27
+ end
28
+ end
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: truelist
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Truelist
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-04-08 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Pure Ruby client for the Truelist.io email validation API. Verify email
14
+ deliverability with zero dependencies. Works anywhere Ruby runs — no Rails required.
15
+ email:
16
+ - support@truelist.io
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - LICENSE
22
+ - README.md
23
+ - lib/truelist.rb
24
+ - lib/truelist/account_info.rb
25
+ - lib/truelist/client.rb
26
+ - lib/truelist/configuration.rb
27
+ - lib/truelist/errors.rb
28
+ - lib/truelist/result.rb
29
+ - lib/truelist/version.rb
30
+ homepage: https://github.com/Truelist-io-Email-Validation/truelist-ruby
31
+ licenses:
32
+ - MIT
33
+ metadata:
34
+ homepage_uri: https://github.com/Truelist-io-Email-Validation/truelist-ruby
35
+ source_code_uri: https://github.com/Truelist-io-Email-Validation/truelist-ruby
36
+ changelog_uri: https://github.com/Truelist-io-Email-Validation/truelist-ruby/blob/main/CHANGELOG.md
37
+ rubygems_mfa_required: 'true'
38
+ post_install_message:
39
+ rdoc_options: []
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '3.0'
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ requirements: []
53
+ rubygems_version: 3.4.10
54
+ signing_key:
55
+ specification_version: 4
56
+ summary: Ruby SDK for Truelist.io email validation
57
+ test_files: []