verity-sdk 1.0.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 +7 -0
- data/LICENSE +21 -0
- data/README.md +174 -0
- data/lib/verity/client.rb +134 -0
- data/lib/verity/errors.rb +43 -0
- data/lib/verity/resources/claims.rb +71 -0
- data/lib/verity/resources/codes.rb +28 -0
- data/lib/verity/resources/compliance.rb +37 -0
- data/lib/verity/resources/coverage.rb +30 -0
- data/lib/verity/resources/drugs.rb +19 -0
- data/lib/verity/resources/policies.rb +57 -0
- data/lib/verity/resources/prior_auth.rb +39 -0
- data/lib/verity/resources/spending.rb +20 -0
- data/lib/verity/resources/webhooks.rb +35 -0
- data/lib/verity/version.rb +5 -0
- data/lib/verity.rb +22 -0
- metadata +105 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 9247cb96ed2f3a0e6f27f0c9551cb8ea45dc099887b90f41572638583a4be001
|
|
4
|
+
data.tar.gz: 882aa32cad3d3c234f14ae7951b2b9ee96f807f28b05187724c1357c6abd80a0
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: c93e3ac2c6d0d528cbb93e82362664b6384db8413f2488c2c8f20f747e7d0f342fab209adbd0938bc2832fbf4f5e1f8eb20812e9c7d9eebbdf4e63ce6897ed55
|
|
7
|
+
data.tar.gz: ac2a3fded1a57e9efb582b7250b63044a3fd5736a039627dd49d1053ae84567d9fb3cccd2482d7b49b93388d98220a595903844b760f6fec20b2448947f68b5a
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Verity API
|
|
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,174 @@
|
|
|
1
|
+
# Verity Ruby SDK
|
|
2
|
+
|
|
3
|
+
Official Ruby client for the [Verity API](https://verity.backworkai.com): Medicare coverage policies, medical code intelligence, prior authorization checks, claim validation, compliance review, and drug formulary evidence.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Install from GitHub until the first RubyGems release is indexed:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
gem 'verity-sdk', git: 'https://github.com/backworkai/verity-ruby.git'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Then install dependencies:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bundle install
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
After the first RubyGems release, install it directly:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
gem install verity-sdk
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Requires Ruby 2.7 or newer.
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
require 'verity'
|
|
31
|
+
|
|
32
|
+
client = Verity::Client.new(api_key: 'vrt_live_YOUR_API_KEY')
|
|
33
|
+
|
|
34
|
+
code = client.codes.lookup('76942', include: ['rvu', 'policies'])
|
|
35
|
+
puts code['data']['description']
|
|
36
|
+
|
|
37
|
+
prior_auth = client.prior_auth.check(
|
|
38
|
+
procedure_codes: ['76942'],
|
|
39
|
+
diagnosis_codes: ['M54.5'],
|
|
40
|
+
state: 'TX',
|
|
41
|
+
payer: 'medicare'
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
puts prior_auth['data']['pa_required']
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Get an API key from the [Verity dashboard](https://verity.backworkai.com/dashboard).
|
|
48
|
+
|
|
49
|
+
## Core Workflows
|
|
50
|
+
|
|
51
|
+
### Code Lookup
|
|
52
|
+
|
|
53
|
+
```ruby
|
|
54
|
+
result = client.codes.lookup(
|
|
55
|
+
'76942',
|
|
56
|
+
include: ['rvu', 'policies'],
|
|
57
|
+
jurisdiction: 'JM',
|
|
58
|
+
fuzzy: true
|
|
59
|
+
)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Policy Search and Retrieval
|
|
63
|
+
|
|
64
|
+
```ruby
|
|
65
|
+
policies = client.policies.list(
|
|
66
|
+
q: 'ultrasound guidance',
|
|
67
|
+
mode: 'keyword',
|
|
68
|
+
policy_type: 'LCD',
|
|
69
|
+
jurisdiction: 'JM',
|
|
70
|
+
status: 'active',
|
|
71
|
+
limit: 25
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
policy = client.policies.get('L33831', include: ['criteria', 'codes'])
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Prior Authorization and Claim Validation
|
|
78
|
+
|
|
79
|
+
```ruby
|
|
80
|
+
prior_auth = client.prior_auth.check(
|
|
81
|
+
procedure_codes: ['76942'],
|
|
82
|
+
diagnosis_codes: ['M54.5'],
|
|
83
|
+
state: 'TX',
|
|
84
|
+
payer: 'medicare'
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
claim = client.claims.validate(
|
|
88
|
+
procedure_codes: ['99213'],
|
|
89
|
+
diagnosis_codes: ['E11.9'],
|
|
90
|
+
payer: 'Medicare',
|
|
91
|
+
state: 'TX',
|
|
92
|
+
date_of_service: '2026-05-23'
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
puts "#{claim['data']['coverage_status']} #{claim['data']['denial_risk']}"
|
|
96
|
+
puts claim['data']['issues']
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Coverage, Spending, and Compliance
|
|
100
|
+
|
|
101
|
+
```ruby
|
|
102
|
+
criteria = client.coverage.search_criteria(
|
|
103
|
+
'diabetes',
|
|
104
|
+
section: 'indications',
|
|
105
|
+
limit: 10
|
|
106
|
+
)
|
|
107
|
+
puts "#{criteria['data'][0]['policy_id']}: #{criteria['data'][0]['policy_title']}"
|
|
108
|
+
|
|
109
|
+
spending = client.spending.by_code(codes: ['T1019', 'T1020'], year: 2023)
|
|
110
|
+
changes = client.compliance.unreviewed(limit: 10)
|
|
111
|
+
stats = client.compliance.stats
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Drug Formulary Evidence
|
|
115
|
+
|
|
116
|
+
```ruby
|
|
117
|
+
formulary = client.drugs.formulary('ozempic', payer: 'all', limit: 5)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Error Handling
|
|
121
|
+
|
|
122
|
+
```ruby
|
|
123
|
+
begin
|
|
124
|
+
result = client.codes.lookup('76942')
|
|
125
|
+
rescue Verity::AuthError => e
|
|
126
|
+
puts "Invalid API key: #{e.message}"
|
|
127
|
+
rescue Verity::ValidationError => e
|
|
128
|
+
puts "Invalid request: #{e.message}"
|
|
129
|
+
rescue Verity::NotFoundError => e
|
|
130
|
+
puts "Resource not found: #{e.message}"
|
|
131
|
+
rescue Verity::RateLimitError => e
|
|
132
|
+
puts "Rate limit exceeded: #{e.message}"
|
|
133
|
+
rescue Verity::APIError => e
|
|
134
|
+
puts "Verity API error: #{e.message}"
|
|
135
|
+
end
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Configuration
|
|
139
|
+
|
|
140
|
+
```ruby
|
|
141
|
+
client = Verity::Client.new(
|
|
142
|
+
api_key: ENV.fetch('VERITY_API_KEY'),
|
|
143
|
+
base_url: 'https://verity.backworkai.com/api/v1',
|
|
144
|
+
timeout: 30
|
|
145
|
+
)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Development
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
bundle install
|
|
152
|
+
ruby -c lib/verity.rb
|
|
153
|
+
gem build verity-sdk.gemspec
|
|
154
|
+
bundle exec rake build
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Release
|
|
158
|
+
|
|
159
|
+
The gem publishes to RubyGems.org as `verity-sdk`.
|
|
160
|
+
|
|
161
|
+
1. Configure a pending RubyGems Trusted Publisher for `backworkai/verity-ruby`, workflow `release.yml`, environment `release`, gem name `verity-sdk`.
|
|
162
|
+
2. Update `lib/verity/version.rb`.
|
|
163
|
+
3. Push a matching tag, for example `v1.0.0`.
|
|
164
|
+
4. The release workflow builds and pushes the gem through RubyGems OIDC trusted publishing.
|
|
165
|
+
|
|
166
|
+
## Support
|
|
167
|
+
|
|
168
|
+
- Documentation: https://verity.backworkai.com/docs
|
|
169
|
+
- Issues: https://github.com/backworkai/verity-ruby/issues
|
|
170
|
+
- Email: support@verity.backworkai.com
|
|
171
|
+
|
|
172
|
+
## License
|
|
173
|
+
|
|
174
|
+
MIT
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Verity
|
|
4
|
+
class Client
|
|
5
|
+
DEFAULT_BASE_URL = 'https://verity.backworkai.com/api/v1'
|
|
6
|
+
DEFAULT_TIMEOUT = 30
|
|
7
|
+
|
|
8
|
+
attr_reader :api_key, :base_url, :timeout
|
|
9
|
+
|
|
10
|
+
def initialize(api_key:, base_url: nil, timeout: nil)
|
|
11
|
+
raise ArgumentError, 'api_key is required' if api_key.nil? || api_key.empty?
|
|
12
|
+
|
|
13
|
+
@api_key = api_key
|
|
14
|
+
@base_url = base_url || DEFAULT_BASE_URL
|
|
15
|
+
@timeout = timeout || DEFAULT_TIMEOUT
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def codes
|
|
19
|
+
@codes ||= Resources::Codes.new(self)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def policies
|
|
23
|
+
@policies ||= Resources::Policies.new(self)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def coverage
|
|
27
|
+
@coverage ||= Resources::Coverage.new(self)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def prior_auth
|
|
31
|
+
@prior_auth ||= Resources::PriorAuth.new(self)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def spending
|
|
35
|
+
@spending ||= Resources::Spending.new(self)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def webhooks
|
|
39
|
+
@webhooks ||= Resources::Webhooks.new(self)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def claims
|
|
43
|
+
@claims ||= Resources::Claims.new(self)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def compliance
|
|
47
|
+
@compliance ||= Resources::Compliance.new(self)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def drugs
|
|
51
|
+
@drugs ||= Resources::Drugs.new(self)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def health
|
|
55
|
+
request(:get, '/health')
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# @private
|
|
59
|
+
def request(method, path, params: nil, body: nil, headers: {})
|
|
60
|
+
response = connection.send(method) do |req|
|
|
61
|
+
req.url path.sub(%r{\A/}, '')
|
|
62
|
+
req.params = params if params
|
|
63
|
+
req.body = body.to_json if body
|
|
64
|
+
req.headers = default_headers.merge(headers)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
handle_response(response)
|
|
68
|
+
rescue Faraday::Error => e
|
|
69
|
+
raise APIError, "Request failed: #{e.message}"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
def connection
|
|
75
|
+
@connection ||= Faraday.new(url: base_url) do |conn|
|
|
76
|
+
conn.request :json
|
|
77
|
+
conn.response :json, content_type: /\bjson$/
|
|
78
|
+
conn.adapter Faraday.default_adapter
|
|
79
|
+
conn.options.timeout = timeout
|
|
80
|
+
conn.options.open_timeout = 10
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def default_headers
|
|
85
|
+
{
|
|
86
|
+
'Authorization' => "Bearer #{api_key}",
|
|
87
|
+
'Content-Type' => 'application/json',
|
|
88
|
+
'User-Agent' => "verity-ruby/#{Verity::VERSION}"
|
|
89
|
+
}
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def handle_response(response)
|
|
93
|
+
rate_limit_info = {
|
|
94
|
+
limit: response.headers['x-ratelimit-limit']&.to_i,
|
|
95
|
+
remaining: response.headers['x-ratelimit-remaining']&.to_i,
|
|
96
|
+
reset: response.headers['x-ratelimit-reset']&.to_i
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if response.status >= 400
|
|
100
|
+
handle_error(response, rate_limit_info)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
response.body
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def handle_error(response, rate_limit_info)
|
|
107
|
+
error_data = response.body.is_a?(Hash) ? response.body : {}
|
|
108
|
+
error = error_data['error'] || {}
|
|
109
|
+
message = error['message'] || "HTTP #{response.status}"
|
|
110
|
+
code = error['code']
|
|
111
|
+
details = error['details']
|
|
112
|
+
|
|
113
|
+
case response.status
|
|
114
|
+
when 401
|
|
115
|
+
raise AuthError.new(message, code: code, details: details)
|
|
116
|
+
when 404
|
|
117
|
+
raise NotFoundError.new(message, code: code, details: details)
|
|
118
|
+
when 400
|
|
119
|
+
raise ValidationError.new(message, code: code, details: details)
|
|
120
|
+
when 429
|
|
121
|
+
raise RateLimitError.new(
|
|
122
|
+
message,
|
|
123
|
+
code: code,
|
|
124
|
+
details: details,
|
|
125
|
+
limit: rate_limit_info[:limit],
|
|
126
|
+
remaining: rate_limit_info[:remaining],
|
|
127
|
+
reset: rate_limit_info[:reset]
|
|
128
|
+
)
|
|
129
|
+
else
|
|
130
|
+
raise APIError.new(message, code: code, details: details, status_code: response.status)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Verity
|
|
4
|
+
class APIError < StandardError
|
|
5
|
+
attr_reader :code, :details, :status_code
|
|
6
|
+
|
|
7
|
+
def initialize(message, code: nil, details: nil, status_code: nil)
|
|
8
|
+
super(message)
|
|
9
|
+
@code = code
|
|
10
|
+
@details = details
|
|
11
|
+
@status_code = status_code
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class AuthError < APIError
|
|
16
|
+
def initialize(message, code: nil, details: nil)
|
|
17
|
+
super(message, code: code, details: details, status_code: 401)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class NotFoundError < APIError
|
|
22
|
+
def initialize(message, code: nil, details: nil)
|
|
23
|
+
super(message, code: code, details: details, status_code: 404)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class ValidationError < APIError
|
|
28
|
+
def initialize(message, code: nil, details: nil)
|
|
29
|
+
super(message, code: code, details: details, status_code: 400)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
class RateLimitError < APIError
|
|
34
|
+
attr_reader :limit, :remaining, :reset
|
|
35
|
+
|
|
36
|
+
def initialize(message, code: nil, details: nil, limit: nil, remaining: nil, reset: nil)
|
|
37
|
+
super(message, code: code, details: details, status_code: 429)
|
|
38
|
+
@limit = limit
|
|
39
|
+
@remaining = remaining
|
|
40
|
+
@reset = reset
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Verity
|
|
4
|
+
module Resources
|
|
5
|
+
class Claims
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def validate(procedure_codes:, payer: nil, plan_type: nil, line_of_business: nil, diagnosis_codes: nil, modifiers: nil, state: nil, date_of_service: nil, site_of_service: nil, provider_specialty: nil, age_category: nil, sex_when_policy_relevant: nil, idempotency_key: nil)
|
|
11
|
+
validate_at_path(
|
|
12
|
+
'/claims/validate',
|
|
13
|
+
procedure_codes: procedure_codes,
|
|
14
|
+
payer: payer,
|
|
15
|
+
plan_type: plan_type,
|
|
16
|
+
line_of_business: line_of_business,
|
|
17
|
+
diagnosis_codes: diagnosis_codes,
|
|
18
|
+
modifiers: modifiers,
|
|
19
|
+
state: state,
|
|
20
|
+
date_of_service: date_of_service,
|
|
21
|
+
site_of_service: site_of_service,
|
|
22
|
+
provider_specialty: provider_specialty,
|
|
23
|
+
age_category: age_category,
|
|
24
|
+
sex_when_policy_relevant: sex_when_policy_relevant,
|
|
25
|
+
idempotency_key: idempotency_key
|
|
26
|
+
)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def validate_legacy(procedure_codes:, payer: nil, plan_type: nil, line_of_business: nil, diagnosis_codes: nil, modifiers: nil, state: nil, date_of_service: nil, site_of_service: nil, provider_specialty: nil, age_category: nil, sex_when_policy_relevant: nil, idempotency_key: nil)
|
|
30
|
+
validate_at_path(
|
|
31
|
+
'/claim-validation',
|
|
32
|
+
procedure_codes: procedure_codes,
|
|
33
|
+
payer: payer,
|
|
34
|
+
plan_type: plan_type,
|
|
35
|
+
line_of_business: line_of_business,
|
|
36
|
+
diagnosis_codes: diagnosis_codes,
|
|
37
|
+
modifiers: modifiers,
|
|
38
|
+
state: state,
|
|
39
|
+
date_of_service: date_of_service,
|
|
40
|
+
site_of_service: site_of_service,
|
|
41
|
+
provider_specialty: provider_specialty,
|
|
42
|
+
age_category: age_category,
|
|
43
|
+
sex_when_policy_relevant: sex_when_policy_relevant,
|
|
44
|
+
idempotency_key: idempotency_key
|
|
45
|
+
)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def validate_at_path(path, procedure_codes:, payer:, plan_type:, line_of_business:, diagnosis_codes:, modifiers:, state:, date_of_service:, site_of_service:, provider_specialty:, age_category:, sex_when_policy_relevant:, idempotency_key:)
|
|
51
|
+
body = { procedure_codes: procedure_codes }
|
|
52
|
+
body[:payer] = payer if payer
|
|
53
|
+
body[:plan_type] = plan_type if plan_type
|
|
54
|
+
body[:line_of_business] = line_of_business if line_of_business
|
|
55
|
+
body[:diagnosis_codes] = diagnosis_codes if diagnosis_codes
|
|
56
|
+
body[:modifiers] = modifiers if modifiers
|
|
57
|
+
body[:state] = state if state
|
|
58
|
+
body[:date_of_service] = date_of_service if date_of_service
|
|
59
|
+
body[:site_of_service] = site_of_service if site_of_service
|
|
60
|
+
body[:provider_specialty] = provider_specialty if provider_specialty
|
|
61
|
+
body[:age_category] = age_category if age_category
|
|
62
|
+
body[:sex_when_policy_relevant] = sex_when_policy_relevant if sex_when_policy_relevant
|
|
63
|
+
|
|
64
|
+
headers = {}
|
|
65
|
+
headers['X-Idempotency-Key'] = idempotency_key if idempotency_key
|
|
66
|
+
|
|
67
|
+
@client.request(:post, path, body: body, headers: headers)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Verity
|
|
4
|
+
module Resources
|
|
5
|
+
class Codes
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def lookup(code, code_system: nil, jurisdiction: nil, include: nil, fuzzy: true)
|
|
11
|
+
params = { code: code }
|
|
12
|
+
params[:code_system] = code_system if code_system
|
|
13
|
+
params[:jurisdiction] = jurisdiction if jurisdiction
|
|
14
|
+
params[:include] = Array(include).join(',') if include
|
|
15
|
+
params[:fuzzy] = fuzzy ? 'true' : 'false'
|
|
16
|
+
|
|
17
|
+
@client.request(:get, '/codes/lookup', params: params)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def batch(codes, code_system: nil, include: nil)
|
|
21
|
+
body = { codes: codes }
|
|
22
|
+
body[:code_system] = code_system if code_system
|
|
23
|
+
body[:include] = include.join(',') if include
|
|
24
|
+
@client.request(:post, '/codes/batch', body: body)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Verity
|
|
4
|
+
module Resources
|
|
5
|
+
class Compliance
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def unreviewed(change_type: nil, cursor: nil, limit: 50)
|
|
11
|
+
params = { limit: limit }
|
|
12
|
+
params[:change_type] = change_type if change_type
|
|
13
|
+
params[:cursor] = cursor if cursor
|
|
14
|
+
|
|
15
|
+
@client.request(:get, '/compliance/unreviewed', params: params)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def acknowledge(diff_id:, notes: nil)
|
|
19
|
+
body = { diff_id: diff_id }
|
|
20
|
+
body[:notes] = notes if notes
|
|
21
|
+
|
|
22
|
+
@client.request(:post, '/compliance/ack', body: body)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def bulk_acknowledge(diff_ids:, notes: nil)
|
|
26
|
+
body = { diff_ids: diff_ids }
|
|
27
|
+
body[:notes] = notes if notes
|
|
28
|
+
|
|
29
|
+
@client.request(:post, '/compliance/ack/bulk', body: body)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def stats
|
|
33
|
+
@client.request(:get, '/compliance/stats')
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Verity
|
|
4
|
+
module Resources
|
|
5
|
+
class Coverage
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def search_criteria(q, section: nil, policy_type: nil, jurisdiction: nil, cursor: nil, limit: 50)
|
|
11
|
+
params = { q: q }
|
|
12
|
+
params[:section] = section if section
|
|
13
|
+
params[:policy_type] = policy_type if policy_type
|
|
14
|
+
params[:jurisdiction] = jurisdiction if jurisdiction
|
|
15
|
+
params[:cursor] = cursor if cursor
|
|
16
|
+
params[:limit] = limit if limit
|
|
17
|
+
|
|
18
|
+
@client.request(:get, '/coverage/criteria', params: params)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def jurisdictions
|
|
22
|
+
@client.request(:get, '/jurisdictions')
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def evaluate(policy_id:, parameters:)
|
|
26
|
+
@client.request(:post, '/coverage/evaluate', body: { policy_id: policy_id, parameters: parameters })
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Verity
|
|
4
|
+
module Resources
|
|
5
|
+
class Drugs
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def formulary(q, payer: 'all', limit: 25)
|
|
11
|
+
@client.request(
|
|
12
|
+
:get,
|
|
13
|
+
'/drugs/formulary',
|
|
14
|
+
params: { q: q, payer: payer, limit: limit }
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Verity
|
|
4
|
+
module Resources
|
|
5
|
+
class Policies
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def list(q: nil, mode: 'keyword', policy_type: nil, jurisdiction: nil, payer: nil, status: 'active', icd10: nil, format: nil, cursor: nil, limit: 50, include: nil)
|
|
11
|
+
params = {}
|
|
12
|
+
params[:q] = q if q
|
|
13
|
+
params[:mode] = mode if mode
|
|
14
|
+
params[:policy_type] = policy_type if policy_type
|
|
15
|
+
params[:jurisdiction] = jurisdiction if jurisdiction
|
|
16
|
+
params[:payer] = payer if payer
|
|
17
|
+
params[:status] = status if status
|
|
18
|
+
params[:icd10] = icd10 if icd10
|
|
19
|
+
params[:format] = format if format
|
|
20
|
+
params[:cursor] = cursor if cursor
|
|
21
|
+
params[:limit] = limit if limit
|
|
22
|
+
params[:include] = Array(include).join(',') if include
|
|
23
|
+
|
|
24
|
+
@client.request(:get, '/policies', params: params)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def get(policy_id, include: nil)
|
|
28
|
+
params = {}
|
|
29
|
+
params[:include] = Array(include).join(',') if include
|
|
30
|
+
|
|
31
|
+
@client.request(:get, "/policies/#{policy_id}", params: params)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def compare(procedure_codes:, policy_type: nil, jurisdictions: nil, idempotency_key: nil)
|
|
35
|
+
body = { procedure_codes: procedure_codes }
|
|
36
|
+
body[:policy_type] = policy_type if policy_type
|
|
37
|
+
body[:jurisdictions] = jurisdictions if jurisdictions
|
|
38
|
+
|
|
39
|
+
headers = {}
|
|
40
|
+
headers['X-Idempotency-Key'] = idempotency_key if idempotency_key
|
|
41
|
+
|
|
42
|
+
@client.request(:post, '/policies/compare', body: body, headers: headers)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def changes(since: nil, policy_id: nil, change_type: nil, cursor: nil, limit: 50)
|
|
46
|
+
params = {}
|
|
47
|
+
params[:since] = since if since
|
|
48
|
+
params[:policy_id] = policy_id if policy_id
|
|
49
|
+
params[:change_type] = change_type if change_type
|
|
50
|
+
params[:cursor] = cursor if cursor
|
|
51
|
+
params[:limit] = limit if limit
|
|
52
|
+
|
|
53
|
+
@client.request(:get, '/policies/changes', params: params)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Verity
|
|
4
|
+
module Resources
|
|
5
|
+
class PriorAuth
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def check(procedure_codes:, diagnosis_codes: nil, state: nil, payer: 'medicare', criteria_page: 1, criteria_per_page: 25, idempotency_key: nil)
|
|
11
|
+
body = { procedure_codes: procedure_codes }
|
|
12
|
+
body[:diagnosis_codes] = diagnosis_codes if diagnosis_codes
|
|
13
|
+
body[:state] = state if state
|
|
14
|
+
body[:payer] = payer if payer
|
|
15
|
+
body[:criteria_page] = criteria_page if criteria_page
|
|
16
|
+
body[:criteria_per_page] = criteria_per_page if criteria_per_page
|
|
17
|
+
|
|
18
|
+
headers = {}
|
|
19
|
+
headers['X-Idempotency-Key'] = idempotency_key if idempotency_key
|
|
20
|
+
|
|
21
|
+
@client.request(:post, '/prior-auth/check', body: body, headers: headers)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def research(procedure_codes:, payer: nil, state: nil, diagnosis_codes: nil, clinical_context: nil, sync: false)
|
|
25
|
+
body = { procedure_codes: procedure_codes, sync: sync }
|
|
26
|
+
body[:payer] = payer if payer
|
|
27
|
+
body[:state] = state if state
|
|
28
|
+
body[:diagnosis_codes] = diagnosis_codes if diagnosis_codes
|
|
29
|
+
body[:clinical_context] = clinical_context if clinical_context
|
|
30
|
+
|
|
31
|
+
@client.request(:post, '/prior-auth/research', body: body)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def get_research(research_id)
|
|
35
|
+
@client.request(:get, "/prior-auth/research/#{research_id}")
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Verity
|
|
4
|
+
module Resources
|
|
5
|
+
class Spending
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def by_code(code: nil, codes: nil, year: nil)
|
|
11
|
+
params = {}
|
|
12
|
+
params[:code] = code if code
|
|
13
|
+
params[:codes] = codes.join(',') if codes
|
|
14
|
+
params[:year] = year if year
|
|
15
|
+
|
|
16
|
+
@client.request(:get, '/spending/by-code', params: params)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Verity
|
|
4
|
+
module Resources
|
|
5
|
+
class Webhooks
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def list
|
|
11
|
+
@client.request(:get, '/webhooks')
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def create(url:, events:)
|
|
15
|
+
@client.request(:post, '/webhooks', body: { url: url, events: events })
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def update(webhook_id, url: nil, events: nil, status: nil)
|
|
19
|
+
body = {}
|
|
20
|
+
body[:url] = url if url
|
|
21
|
+
body[:events] = events if events
|
|
22
|
+
body[:status] = status if status
|
|
23
|
+
@client.request(:patch, "/webhooks/#{webhook_id}", body: body)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def delete(webhook_id)
|
|
27
|
+
@client.request(:delete, "/webhooks/#{webhook_id}")
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def test(webhook_id)
|
|
31
|
+
@client.request(:post, "/webhooks/#{webhook_id}/test")
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
data/lib/verity.rb
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'faraday'
|
|
4
|
+
require 'faraday/retry'
|
|
5
|
+
require 'json'
|
|
6
|
+
|
|
7
|
+
require_relative 'verity/version'
|
|
8
|
+
require_relative 'verity/errors'
|
|
9
|
+
require_relative 'verity/client'
|
|
10
|
+
require_relative 'verity/resources/codes'
|
|
11
|
+
require_relative 'verity/resources/policies'
|
|
12
|
+
require_relative 'verity/resources/coverage'
|
|
13
|
+
require_relative 'verity/resources/prior_auth'
|
|
14
|
+
require_relative 'verity/resources/spending'
|
|
15
|
+
require_relative 'verity/resources/webhooks'
|
|
16
|
+
require_relative 'verity/resources/claims'
|
|
17
|
+
require_relative 'verity/resources/compliance'
|
|
18
|
+
require_relative 'verity/resources/drugs'
|
|
19
|
+
|
|
20
|
+
module Verity
|
|
21
|
+
class Error < StandardError; end
|
|
22
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: verity-sdk
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Verity API
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-05-23 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: faraday
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '2.0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '2.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: faraday-retry
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '2.0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '2.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rake
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '13.0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '13.0'
|
|
55
|
+
description: Ruby client library for the Verity API - Medicare coverage policies,
|
|
56
|
+
prior authorization requirements, and medical code lookups
|
|
57
|
+
email:
|
|
58
|
+
- support@verity.backworkai.com
|
|
59
|
+
executables: []
|
|
60
|
+
extensions: []
|
|
61
|
+
extra_rdoc_files: []
|
|
62
|
+
files:
|
|
63
|
+
- LICENSE
|
|
64
|
+
- README.md
|
|
65
|
+
- lib/verity.rb
|
|
66
|
+
- lib/verity/client.rb
|
|
67
|
+
- lib/verity/errors.rb
|
|
68
|
+
- lib/verity/resources/claims.rb
|
|
69
|
+
- lib/verity/resources/codes.rb
|
|
70
|
+
- lib/verity/resources/compliance.rb
|
|
71
|
+
- lib/verity/resources/coverage.rb
|
|
72
|
+
- lib/verity/resources/drugs.rb
|
|
73
|
+
- lib/verity/resources/policies.rb
|
|
74
|
+
- lib/verity/resources/prior_auth.rb
|
|
75
|
+
- lib/verity/resources/spending.rb
|
|
76
|
+
- lib/verity/resources/webhooks.rb
|
|
77
|
+
- lib/verity/version.rb
|
|
78
|
+
homepage: https://github.com/backworkai/verity-ruby
|
|
79
|
+
licenses:
|
|
80
|
+
- MIT
|
|
81
|
+
metadata:
|
|
82
|
+
allowed_push_host: https://rubygems.org
|
|
83
|
+
homepage_uri: https://github.com/backworkai/verity-ruby
|
|
84
|
+
source_code_uri: https://github.com/backworkai/verity-ruby
|
|
85
|
+
rubygems_mfa_required: 'true'
|
|
86
|
+
post_install_message:
|
|
87
|
+
rdoc_options: []
|
|
88
|
+
require_paths:
|
|
89
|
+
- lib
|
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
91
|
+
requirements:
|
|
92
|
+
- - ">="
|
|
93
|
+
- !ruby/object:Gem::Version
|
|
94
|
+
version: 2.7.0
|
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
96
|
+
requirements:
|
|
97
|
+
- - ">="
|
|
98
|
+
- !ruby/object:Gem::Version
|
|
99
|
+
version: '0'
|
|
100
|
+
requirements: []
|
|
101
|
+
rubygems_version: 3.0.3.1
|
|
102
|
+
signing_key:
|
|
103
|
+
specification_version: 4
|
|
104
|
+
summary: Ruby SDK for the Verity API
|
|
105
|
+
test_files: []
|