safetykit 0.51.0 → 0.53.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: edca5667de202b072736d856befde1d6dc5c05159172501817845236aef204f0
4
- data.tar.gz: 80ab0c4d50b502d7bc63be3358cb7ce94f3075a1d30b7f2716a3e33ca9c90aeb
3
+ metadata.gz: e99118dc813839214ef54180d8c8b7fd0528ddeb49f48d2eecde4ec540bbaa41
4
+ data.tar.gz: '08c93665f10cc3be1ce9a44781e2c60b6ede81d25fbec916f6bd29be2ba62558'
5
5
  SHA512:
6
- metadata.gz: 47729951a4064258d19e89c45cbbcdbda4e4a9a1ef7672114047c0bf7cc974b8298f5221c8c1d18e8285d9749f8cc1789900d07895c29df45fcf0048ff917b6d
7
- data.tar.gz: 3eb38d4ff7ed1cfae936e0bddf738063776594954a2e8c36ba68ca37caf528e364234636c9202eb3e6b029e7de827d74c1a8f43d1c7dc159f69cd6e889e8c654
6
+ metadata.gz: 7db211c300da39bc4e7c0dd74ca7220bfc38aa23df5c597a054ab72cd4156859aa583025ff7292c02121c78c7743d27912b72374a7a70ae0f16ab21bef5953ae
7
+ data.tar.gz: 2569223e2d2779daab8a6a364fcde41473e1dfc7af8cb345b790eb590f74e02b47b79f03e46ee42f63468fe6718693292962f8f2611aede4d82ea86024151c84
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.53.0 (2026-08-06)
4
+
5
+ Full Changelog: [v0.52.0...v0.53.0](https://github.com/GetSafetyKit/safetykit-ruby/compare/v0.52.0...v0.53.0)
6
+
7
+ ### Features
8
+
9
+ * **api:** api update ([4c74263](https://github.com/GetSafetyKit/safetykit-ruby/commit/4c74263a51e3176b1ff3660c1b5ac14d0dcd3559))
10
+
11
+ ## 0.52.0 (2026-08-05)
12
+
13
+ Full Changelog: [v0.51.0...v0.52.0](https://github.com/GetSafetyKit/safetykit-ruby/compare/v0.51.0...v0.52.0)
14
+
15
+ ### Features
16
+
17
+ * **api:** api update ([9d34342](https://github.com/GetSafetyKit/safetykit-ruby/commit/9d343420a3716e47e99f484881f25944a3468e43))
18
+
3
19
  ## 0.51.0 (2026-08-05)
4
20
 
5
21
  Full Changelog: [v0.50.0...v0.51.0](https://github.com/GetSafetyKit/safetykit-ruby/compare/v0.50.0...v0.51.0)
data/README.md CHANGED
@@ -17,7 +17,7 @@ To use this gem, install via Bundler by adding the following to your application
17
17
  <!-- x-release-please-start-version -->
18
18
 
19
19
  ```ruby
20
- gem "safetykit", "~> 0.51.0"
20
+ gem "safetykit", "~> 0.53.0"
21
21
  ```
22
22
 
23
23
  <!-- x-release-please-end -->
@@ -7,26 +7,22 @@ module SafetyKit
7
7
  extend SafetyKit::Internal::Type::RequestParameters::Converter
8
8
  include SafetyKit::Internal::Type::RequestParameters
9
9
 
10
- # @!attribute entity_id
11
- # Your stable identifier for the entity this content belongs to, such as a user,
12
- # listing, or message thread.
10
+ # @!attribute user_id
11
+ # Your stable identifier for the user this content belongs to.
13
12
  #
14
13
  # @return [String]
15
- required :entity_id, String
14
+ required :user_id, String
16
15
 
17
16
  # @!attribute content_id
18
- # Your identifier for this piece of content the same content_id you send on
19
- # /v1/events. When provided, the event this call records deduplicates against the
20
- # same upload posted through the events API, so sending both never double-counts
21
- # the content.
17
+ # Your identifier for this content, matching the content_id sent on /v1/events.
18
+ # Prevents double-counting content submitted to both endpoints.
22
19
  #
23
20
  # @return [String, nil]
24
21
  optional :content_id, String
25
22
 
26
23
  # @!attribute images
27
24
  # Images to classify, each as base64-encoded image bytes, raw or as a data URI. At
28
- # most 4 images. The full request body must stay under 6MB, which allows roughly
29
- # 4.4MB of raw image bytes after base64 inflation.
25
+ # most 20 images, 5MB each.
30
26
  #
31
27
  # @return [Array<String>, nil]
32
28
  optional :images, SafetyKit::Internal::Type::ArrayOf[String]
@@ -38,24 +34,24 @@ module SafetyKit
38
34
  optional :metadata, SafetyKit::Internal::Type::HashOf[SafetyKit::Internal::Type::Unknown, nil?: true]
39
35
 
40
36
  # @!attribute text
41
- # User-authored text to classify. At most 20000 characters.
37
+ # User-authored text to classify. At most 16000 characters.
42
38
  #
43
39
  # @return [String, nil]
44
40
  optional :text, String
45
41
 
46
- # @!method initialize(entity_id:, content_id: nil, images: nil, metadata: nil, text: nil, request_options: {})
42
+ # @!method initialize(user_id:, content_id: nil, images: nil, metadata: nil, text: nil, request_options: {})
47
43
  # Some parameter documentations has been truncated, see
48
44
  # {SafetyKit::Models::ContentCreateParams} for more details.
49
45
  #
50
- # @param entity_id [String] Your stable identifier for the entity this content belongs to, such as a user, l
46
+ # @param user_id [String] Your stable identifier for the user this content belongs to.
51
47
  #
52
- # @param content_id [String] Your identifier for this piece of content the same content_id you send on /v1/
48
+ # @param content_id [String] Your identifier for this content, matching the content_id sent on /v1/events. Pr
53
49
  #
54
50
  # @param images [Array<String>] Images to classify, each as base64-encoded image bytes, raw or as a data URI. At
55
51
  #
56
52
  # @param metadata [Hash{Symbol=>Object, nil}] Additional product context for this content. At most 8KB when serialized.
57
53
  #
58
- # @param text [String] User-authored text to classify. At most 20000 characters.
54
+ # @param text [String] User-authored text to classify. At most 16000 characters.
59
55
  #
60
56
  # @param request_options [SafetyKit::RequestOptions, Hash{Symbol=>Object}]
61
57
  end
@@ -11,32 +11,18 @@ module SafetyKit
11
11
  required :content_id, String
12
12
 
13
13
  # @!attribute decision
14
- # SafetyKit's decision for the submitted content: approve (no violation found),
15
- # reject (violating), or review (needs human review).
14
+ # Overall decision: match if any policy matched, review if any policy needs
15
+ # review, not_match otherwise.
16
16
  #
17
17
  # @return [Symbol, SafetyKit::Models::ContentCreateResponse::Decision]
18
18
  required :decision, enum: -> { SafetyKit::Models::ContentCreateResponse::Decision }
19
19
 
20
- # @!attribute entity_id
21
- # The entity_id from the request.
20
+ # @!attribute policies
21
+ # Per-policy results for the submitted content.
22
22
  #
23
- # @return [String]
24
- required :entity_id, String
25
-
26
- # @!attribute escalation
27
- # Escalation outcome for this request: none (the request never entered the
28
- # escalation band), completed (the escalated verdict is reflected in decision), or
29
- # timed_out (escalation did not finish in budget, so decision is a provisional
30
- # review).
31
- #
32
- # @return [Symbol, SafetyKit::Models::ContentCreateResponse::Escalation]
33
- required :escalation, enum: -> { SafetyKit::Models::ContentCreateResponse::Escalation }
34
-
35
- # @!attribute mirrored
36
- # Whether SafetyKit mirrored the submitted content for later review.
37
- #
38
- # @return [Boolean]
39
- required :mirrored, SafetyKit::Internal::Type::Boolean
23
+ # @return [Array<SafetyKit::Models::ContentCreateResponse::Policy>]
24
+ required :policies,
25
+ -> { SafetyKit::Internal::Type::ArrayOf[SafetyKit::Models::ContentCreateResponse::Policy] }
40
26
 
41
27
  # @!attribute reference_set_matches
42
28
  # Reference set matches found for the submitted content.
@@ -45,14 +31,13 @@ module SafetyKit
45
31
  required :reference_set_matches,
46
32
  -> { SafetyKit::Internal::Type::ArrayOf[SafetyKit::Models::ContentCreateResponse::ReferenceSetMatch] }
47
33
 
48
- # @!attribute scores
49
- # Classifier scores produced for the submitted content.
34
+ # @!attribute user_id
35
+ # The user_id from the request.
50
36
  #
51
- # @return [Array<SafetyKit::Models::ContentCreateResponse::Score>]
52
- required :scores,
53
- -> { SafetyKit::Internal::Type::ArrayOf[SafetyKit::Models::ContentCreateResponse::Score] }
37
+ # @return [String]
38
+ required :user_id, String
54
39
 
55
- # @!method initialize(content_id:, decision:, entity_id:, escalation:, mirrored:, reference_set_matches:, scores:)
40
+ # @!method initialize(content_id:, decision:, policies:, reference_set_matches:, user_id:)
56
41
  # Some parameter documentations has been truncated, see
57
42
  # {SafetyKit::Models::ContentCreateResponse} for more details.
58
43
  #
@@ -60,48 +45,107 @@ module SafetyKit
60
45
  #
61
46
  # @param content_id [String] SafetyKit identifier for the classified content.
62
47
  #
63
- # @param decision [Symbol, SafetyKit::Models::ContentCreateResponse::Decision] SafetyKit's decision for the submitted content: approve (no violation found), re
64
- #
65
- # @param entity_id [String] The entity_id from the request.
66
- #
67
- # @param escalation [Symbol, SafetyKit::Models::ContentCreateResponse::Escalation] Escalation outcome for this request: none (the request never entered the escalat
48
+ # @param decision [Symbol, SafetyKit::Models::ContentCreateResponse::Decision] Overall decision: match if any policy matched, review if any policy needs review
68
49
  #
69
- # @param mirrored [Boolean] Whether SafetyKit mirrored the submitted content for later review.
50
+ # @param policies [Array<SafetyKit::Models::ContentCreateResponse::Policy>] Per-policy results for the submitted content.
70
51
  #
71
52
  # @param reference_set_matches [Array<SafetyKit::Models::ContentCreateResponse::ReferenceSetMatch>] Reference set matches found for the submitted content.
72
53
  #
73
- # @param scores [Array<SafetyKit::Models::ContentCreateResponse::Score>] Classifier scores produced for the submitted content.
54
+ # @param user_id [String] The user_id from the request.
74
55
 
75
- # SafetyKit's decision for the submitted content: approve (no violation found),
76
- # reject (violating), or review (needs human review).
56
+ # Overall decision: match if any policy matched, review if any policy needs
57
+ # review, not_match otherwise.
77
58
  #
78
59
  # @see SafetyKit::Models::ContentCreateResponse#decision
79
60
  module Decision
80
61
  extend SafetyKit::Internal::Type::Enum
81
62
 
82
- APPROVE = :approve
83
- REJECT = :reject
63
+ MATCH = :match
64
+ NOT_MATCH = :not_match
84
65
  REVIEW = :review
85
66
 
86
67
  # @!method self.values
87
68
  # @return [Array<Symbol>]
88
69
  end
89
70
 
90
- # Escalation outcome for this request: none (the request never entered the
91
- # escalation band), completed (the escalated verdict is reflected in decision), or
92
- # timed_out (escalation did not finish in budget, so decision is a provisional
93
- # review).
94
- #
95
- # @see SafetyKit::Models::ContentCreateResponse#escalation
96
- module Escalation
97
- extend SafetyKit::Internal::Type::Enum
71
+ class Policy < SafetyKit::Internal::Type::BaseModel
72
+ # @!attribute decision
73
+ # Decision for the submitted content: match (violates the policy), not_match (does
74
+ # not violate), or review (needs human review).
75
+ #
76
+ # @return [Symbol, SafetyKit::Models::ContentCreateResponse::Policy::Decision]
77
+ required :decision, enum: -> { SafetyKit::Models::ContentCreateResponse::Policy::Decision }
98
78
 
99
- NONE = :none
100
- COMPLETED = :completed
101
- TIMED_OUT = :timed_out
79
+ # @!attribute escalation
80
+ # Escalation outcome: none (no escalation ran), completed (verdict reflected in
81
+ # decision), or timed_out (decision is a provisional review).
82
+ #
83
+ # @return [Symbol, SafetyKit::Models::ContentCreateResponse::Policy::Escalation]
84
+ required :escalation, enum: -> { SafetyKit::Models::ContentCreateResponse::Policy::Escalation }
102
85
 
103
- # @!method self.values
104
- # @return [Array<Symbol>]
86
+ # @!attribute policy_id
87
+ # Identifier of the policy.
88
+ #
89
+ # @return [String]
90
+ required :policy_id, String
91
+
92
+ # @!attribute score
93
+ # Policy score between 0 and 1. Higher means more likely violating.
94
+ #
95
+ # @return [Float]
96
+ required :score, Float
97
+
98
+ # @!attribute version
99
+ # Version of the policy.
100
+ #
101
+ # @return [String]
102
+ required :version, String
103
+
104
+ # @!method initialize(decision:, escalation:, policy_id:, score:, version:)
105
+ # Some parameter documentations has been truncated, see
106
+ # {SafetyKit::Models::ContentCreateResponse::Policy} for more details.
107
+ #
108
+ # Result for one policy evaluated against the submitted content.
109
+ #
110
+ # @param decision [Symbol, SafetyKit::Models::ContentCreateResponse::Policy::Decision] Decision for the submitted content: match (violates the policy), not_match (does
111
+ #
112
+ # @param escalation [Symbol, SafetyKit::Models::ContentCreateResponse::Policy::Escalation] Escalation outcome: none (no escalation ran), completed (verdict reflected in de
113
+ #
114
+ # @param policy_id [String] Identifier of the policy.
115
+ #
116
+ # @param score [Float] Policy score between 0 and 1. Higher means more likely violating.
117
+ #
118
+ # @param version [String] Version of the policy.
119
+
120
+ # Decision for the submitted content: match (violates the policy), not_match (does
121
+ # not violate), or review (needs human review).
122
+ #
123
+ # @see SafetyKit::Models::ContentCreateResponse::Policy#decision
124
+ module Decision
125
+ extend SafetyKit::Internal::Type::Enum
126
+
127
+ MATCH = :match
128
+ NOT_MATCH = :not_match
129
+ REVIEW = :review
130
+
131
+ # @!method self.values
132
+ # @return [Array<Symbol>]
133
+ end
134
+
135
+ # Escalation outcome: none (no escalation ran), completed (verdict reflected in
136
+ # decision), or timed_out (decision is a provisional review).
137
+ #
138
+ # @see SafetyKit::Models::ContentCreateResponse::Policy#escalation
139
+ module Escalation
140
+ extend SafetyKit::Internal::Type::Enum
141
+
142
+ NONE = :none
143
+ COMPLETED = :completed
144
+ TIMED_OUT = :timed_out
145
+
146
+ # @!method self.values
147
+ # @return [Array<Symbol>]
148
+ end
105
149
  end
106
150
 
107
151
  class ReferenceSetMatch < SafetyKit::Internal::Type::BaseModel
@@ -124,35 +168,6 @@ module SafetyKit
124
168
  #
125
169
  # @param similarity [Float] Similarity between the submitted content and the matched reference set entry.
126
170
  end
127
-
128
- class Score < SafetyKit::Internal::Type::BaseModel
129
- # @!attribute classifier_id
130
- # Identifier of the classifier that produced this score.
131
- #
132
- # @return [String]
133
- required :classifier_id, String
134
-
135
- # @!attribute score
136
- # Classifier score between 0 and 1. Higher means more likely violating.
137
- #
138
- # @return [Float]
139
- required :score, Float
140
-
141
- # @!attribute version
142
- # Version of the classifier that produced this score.
143
- #
144
- # @return [String]
145
- required :version, String
146
-
147
- # @!method initialize(classifier_id:, score:, version:)
148
- # Score produced by one classifier for the submitted content.
149
- #
150
- # @param classifier_id [String] Identifier of the classifier that produced this score.
151
- #
152
- # @param score [Float] Classifier score between 0 and 1. Higher means more likely violating.
153
- #
154
- # @param version [String] Version of the classifier that produced this score.
155
- end
156
171
  end
157
172
  end
158
173
  end
@@ -9,21 +9,20 @@ module SafetyKit
9
9
  # {SafetyKit::Models::ContentCreateParams} for more details.
10
10
  #
11
11
  # Classify a piece of content synchronously. Send user-authored text, images, or
12
- # both, and receive a decision (approve, reject, or review) with classifier scores
13
- # and reference set matches in the response. The full request body must stay under
14
- # 6MB, which allows roughly 4.4MB of raw image bytes after base64 inflation.
12
+ # both, and receive per-policy results with an overall decision (match, not_match,
13
+ # or review) in the response. Requests have a maximum size of 6MB.
15
14
  #
16
- # @overload create(entity_id:, content_id: nil, images: nil, metadata: nil, text: nil, request_options: {})
15
+ # @overload create(user_id:, content_id: nil, images: nil, metadata: nil, text: nil, request_options: {})
17
16
  #
18
- # @param entity_id [String] Your stable identifier for the entity this content belongs to, such as a user, l
17
+ # @param user_id [String] Your stable identifier for the user this content belongs to.
19
18
  #
20
- # @param content_id [String] Your identifier for this piece of content the same content_id you send on /v1/
19
+ # @param content_id [String] Your identifier for this content, matching the content_id sent on /v1/events. Pr
21
20
  #
22
21
  # @param images [Array<String>] Images to classify, each as base64-encoded image bytes, raw or as a data URI. At
23
22
  #
24
23
  # @param metadata [Hash{Symbol=>Object, nil}] Additional product context for this content. At most 8KB when serialized.
25
24
  #
26
- # @param text [String] User-authored text to classify. At most 20000 characters.
25
+ # @param text [String] User-authored text to classify. At most 16000 characters.
27
26
  #
28
27
  # @param request_options [SafetyKit::RequestOptions, Hash{Symbol=>Object}, nil]
29
28
  #
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SafetyKit
4
- VERSION = "0.51.0"
4
+ VERSION = "0.53.0"
5
5
  end
@@ -11,15 +11,12 @@ module SafetyKit
11
11
  T.any(SafetyKit::ContentCreateParams, SafetyKit::Internal::AnyHash)
12
12
  end
13
13
 
14
- # Your stable identifier for the entity this content belongs to, such as a user,
15
- # listing, or message thread.
14
+ # Your stable identifier for the user this content belongs to.
16
15
  sig { returns(String) }
17
- attr_accessor :entity_id
16
+ attr_accessor :user_id
18
17
 
19
- # Your identifier for this piece of content the same content_id you send on
20
- # /v1/events. When provided, the event this call records deduplicates against the
21
- # same upload posted through the events API, so sending both never double-counts
22
- # the content.
18
+ # Your identifier for this content, matching the content_id sent on /v1/events.
19
+ # Prevents double-counting content submitted to both endpoints.
23
20
  sig { returns(T.nilable(String)) }
24
21
  attr_reader :content_id
25
22
 
@@ -27,8 +24,7 @@ module SafetyKit
27
24
  attr_writer :content_id
28
25
 
29
26
  # Images to classify, each as base64-encoded image bytes, raw or as a data URI. At
30
- # most 4 images. The full request body must stay under 6MB, which allows roughly
31
- # 4.4MB of raw image bytes after base64 inflation.
27
+ # most 20 images, 5MB each.
32
28
  sig { returns(T.nilable(T::Array[String])) }
33
29
  attr_reader :images
34
30
 
@@ -42,7 +38,7 @@ module SafetyKit
42
38
  sig { params(metadata: T::Hash[Symbol, T.nilable(T.anything)]).void }
43
39
  attr_writer :metadata
44
40
 
45
- # User-authored text to classify. At most 20000 characters.
41
+ # User-authored text to classify. At most 16000 characters.
46
42
  sig { returns(T.nilable(String)) }
47
43
  attr_reader :text
48
44
 
@@ -51,7 +47,7 @@ module SafetyKit
51
47
 
52
48
  sig do
53
49
  params(
54
- entity_id: String,
50
+ user_id: String,
55
51
  content_id: String,
56
52
  images: T::Array[String],
57
53
  metadata: T::Hash[Symbol, T.nilable(T.anything)],
@@ -60,21 +56,17 @@ module SafetyKit
60
56
  ).returns(T.attached_class)
61
57
  end
62
58
  def self.new(
63
- # Your stable identifier for the entity this content belongs to, such as a user,
64
- # listing, or message thread.
65
- entity_id:,
66
- # Your identifier for this piece of content the same content_id you send on
67
- # /v1/events. When provided, the event this call records deduplicates against the
68
- # same upload posted through the events API, so sending both never double-counts
69
- # the content.
59
+ # Your stable identifier for the user this content belongs to.
60
+ user_id:,
61
+ # Your identifier for this content, matching the content_id sent on /v1/events.
62
+ # Prevents double-counting content submitted to both endpoints.
70
63
  content_id: nil,
71
64
  # Images to classify, each as base64-encoded image bytes, raw or as a data URI. At
72
- # most 4 images. The full request body must stay under 6MB, which allows roughly
73
- # 4.4MB of raw image bytes after base64 inflation.
65
+ # most 20 images, 5MB each.
74
66
  images: nil,
75
67
  # Additional product context for this content. At most 8KB when serialized.
76
68
  metadata: nil,
77
- # User-authored text to classify. At most 20000 characters.
69
+ # User-authored text to classify. At most 16000 characters.
78
70
  text: nil,
79
71
  request_options: {}
80
72
  )
@@ -83,7 +75,7 @@ module SafetyKit
83
75
  sig do
84
76
  override.returns(
85
77
  {
86
- entity_id: String,
78
+ user_id: String,
87
79
  content_id: String,
88
80
  images: T::Array[String],
89
81
  metadata: T::Hash[Symbol, T.nilable(T.anything)],
@@ -15,8 +15,8 @@ module SafetyKit
15
15
  sig { returns(String) }
16
16
  attr_accessor :content_id
17
17
 
18
- # SafetyKit's decision for the submitted content: approve (no violation found),
19
- # reject (violating), or review (needs human review).
18
+ # Overall decision: match if any policy matched, review if any policy needs
19
+ # review, not_match otherwise.
20
20
  sig do
21
21
  returns(
22
22
  SafetyKit::Models::ContentCreateResponse::Decision::TaggedSymbol
@@ -24,24 +24,11 @@ module SafetyKit
24
24
  end
25
25
  attr_accessor :decision
26
26
 
27
- # The entity_id from the request.
28
- sig { returns(String) }
29
- attr_accessor :entity_id
30
-
31
- # Escalation outcome for this request: none (the request never entered the
32
- # escalation band), completed (the escalated verdict is reflected in decision), or
33
- # timed_out (escalation did not finish in budget, so decision is a provisional
34
- # review).
27
+ # Per-policy results for the submitted content.
35
28
  sig do
36
- returns(
37
- SafetyKit::Models::ContentCreateResponse::Escalation::TaggedSymbol
38
- )
29
+ returns(T::Array[SafetyKit::Models::ContentCreateResponse::Policy])
39
30
  end
40
- attr_accessor :escalation
41
-
42
- # Whether SafetyKit mirrored the submitted content for later review.
43
- sig { returns(T::Boolean) }
44
- attr_accessor :mirrored
31
+ attr_accessor :policies
45
32
 
46
33
  # Reference set matches found for the submitted content.
47
34
  sig do
@@ -51,9 +38,9 @@ module SafetyKit
51
38
  end
52
39
  attr_accessor :reference_set_matches
53
40
 
54
- # Classifier scores produced for the submitted content.
55
- sig { returns(T::Array[SafetyKit::Models::ContentCreateResponse::Score]) }
56
- attr_accessor :scores
41
+ # The user_id from the request.
42
+ sig { returns(String) }
43
+ attr_accessor :user_id
57
44
 
58
45
  # Synchronous classification result for the submitted content.
59
46
  sig do
@@ -61,37 +48,27 @@ module SafetyKit
61
48
  content_id: String,
62
49
  decision:
63
50
  SafetyKit::Models::ContentCreateResponse::Decision::OrSymbol,
64
- entity_id: String,
65
- escalation:
66
- SafetyKit::Models::ContentCreateResponse::Escalation::OrSymbol,
67
- mirrored: T::Boolean,
51
+ policies:
52
+ T::Array[SafetyKit::Models::ContentCreateResponse::Policy::OrHash],
68
53
  reference_set_matches:
69
54
  T::Array[
70
55
  SafetyKit::Models::ContentCreateResponse::ReferenceSetMatch::OrHash
71
56
  ],
72
- scores:
73
- T::Array[SafetyKit::Models::ContentCreateResponse::Score::OrHash]
57
+ user_id: String
74
58
  ).returns(T.attached_class)
75
59
  end
76
60
  def self.new(
77
61
  # SafetyKit identifier for the classified content.
78
62
  content_id:,
79
- # SafetyKit's decision for the submitted content: approve (no violation found),
80
- # reject (violating), or review (needs human review).
63
+ # Overall decision: match if any policy matched, review if any policy needs
64
+ # review, not_match otherwise.
81
65
  decision:,
82
- # The entity_id from the request.
83
- entity_id:,
84
- # Escalation outcome for this request: none (the request never entered the
85
- # escalation band), completed (the escalated verdict is reflected in decision), or
86
- # timed_out (escalation did not finish in budget, so decision is a provisional
87
- # review).
88
- escalation:,
89
- # Whether SafetyKit mirrored the submitted content for later review.
90
- mirrored:,
66
+ # Per-policy results for the submitted content.
67
+ policies:,
91
68
  # Reference set matches found for the submitted content.
92
69
  reference_set_matches:,
93
- # Classifier scores produced for the submitted content.
94
- scores:
70
+ # The user_id from the request.
71
+ user_id:
95
72
  )
96
73
  end
97
74
 
@@ -101,23 +78,21 @@ module SafetyKit
101
78
  content_id: String,
102
79
  decision:
103
80
  SafetyKit::Models::ContentCreateResponse::Decision::TaggedSymbol,
104
- entity_id: String,
105
- escalation:
106
- SafetyKit::Models::ContentCreateResponse::Escalation::TaggedSymbol,
107
- mirrored: T::Boolean,
81
+ policies:
82
+ T::Array[SafetyKit::Models::ContentCreateResponse::Policy],
108
83
  reference_set_matches:
109
84
  T::Array[
110
85
  SafetyKit::Models::ContentCreateResponse::ReferenceSetMatch
111
86
  ],
112
- scores: T::Array[SafetyKit::Models::ContentCreateResponse::Score]
87
+ user_id: String
113
88
  }
114
89
  )
115
90
  end
116
91
  def to_hash
117
92
  end
118
93
 
119
- # SafetyKit's decision for the submitted content: approve (no violation found),
120
- # reject (violating), or review (needs human review).
94
+ # Overall decision: match if any policy matched, review if any policy needs
95
+ # review, not_match otherwise.
121
96
  module Decision
122
97
  extend SafetyKit::Internal::Type::Enum
123
98
 
@@ -127,14 +102,14 @@ module SafetyKit
127
102
  end
128
103
  OrSymbol = T.type_alias { T.any(Symbol, String) }
129
104
 
130
- APPROVE =
105
+ MATCH =
131
106
  T.let(
132
- :approve,
107
+ :match,
133
108
  SafetyKit::Models::ContentCreateResponse::Decision::TaggedSymbol
134
109
  )
135
- REJECT =
110
+ NOT_MATCH =
136
111
  T.let(
137
- :reject,
112
+ :not_match,
138
113
  SafetyKit::Models::ContentCreateResponse::Decision::TaggedSymbol
139
114
  )
140
115
  REVIEW =
@@ -154,43 +129,169 @@ module SafetyKit
154
129
  end
155
130
  end
156
131
 
157
- # Escalation outcome for this request: none (the request never entered the
158
- # escalation band), completed (the escalated verdict is reflected in decision), or
159
- # timed_out (escalation did not finish in budget, so decision is a provisional
160
- # review).
161
- module Escalation
162
- extend SafetyKit::Internal::Type::Enum
163
-
164
- TaggedSymbol =
132
+ class Policy < SafetyKit::Internal::Type::BaseModel
133
+ OrHash =
165
134
  T.type_alias do
166
- T.all(Symbol, SafetyKit::Models::ContentCreateResponse::Escalation)
135
+ T.any(
136
+ SafetyKit::Models::ContentCreateResponse::Policy,
137
+ SafetyKit::Internal::AnyHash
138
+ )
167
139
  end
168
- OrSymbol = T.type_alias { T.any(Symbol, String) }
169
140
 
170
- NONE =
171
- T.let(
172
- :none,
173
- SafetyKit::Models::ContentCreateResponse::Escalation::TaggedSymbol
174
- )
175
- COMPLETED =
176
- T.let(
177
- :completed,
178
- SafetyKit::Models::ContentCreateResponse::Escalation::TaggedSymbol
141
+ # Decision for the submitted content: match (violates the policy), not_match (does
142
+ # not violate), or review (needs human review).
143
+ sig do
144
+ returns(
145
+ SafetyKit::Models::ContentCreateResponse::Policy::Decision::TaggedSymbol
179
146
  )
180
- TIMED_OUT =
181
- T.let(
182
- :timed_out,
183
- SafetyKit::Models::ContentCreateResponse::Escalation::TaggedSymbol
147
+ end
148
+ attr_accessor :decision
149
+
150
+ # Escalation outcome: none (no escalation ran), completed (verdict reflected in
151
+ # decision), or timed_out (decision is a provisional review).
152
+ sig do
153
+ returns(
154
+ SafetyKit::Models::ContentCreateResponse::Policy::Escalation::TaggedSymbol
184
155
  )
156
+ end
157
+ attr_accessor :escalation
158
+
159
+ # Identifier of the policy.
160
+ sig { returns(String) }
161
+ attr_accessor :policy_id
162
+
163
+ # Policy score between 0 and 1. Higher means more likely violating.
164
+ sig { returns(Float) }
165
+ attr_accessor :score
166
+
167
+ # Version of the policy.
168
+ sig { returns(String) }
169
+ attr_accessor :version
170
+
171
+ # Result for one policy evaluated against the submitted content.
172
+ sig do
173
+ params(
174
+ decision:
175
+ SafetyKit::Models::ContentCreateResponse::Policy::Decision::OrSymbol,
176
+ escalation:
177
+ SafetyKit::Models::ContentCreateResponse::Policy::Escalation::OrSymbol,
178
+ policy_id: String,
179
+ score: Float,
180
+ version: String
181
+ ).returns(T.attached_class)
182
+ end
183
+ def self.new(
184
+ # Decision for the submitted content: match (violates the policy), not_match (does
185
+ # not violate), or review (needs human review).
186
+ decision:,
187
+ # Escalation outcome: none (no escalation ran), completed (verdict reflected in
188
+ # decision), or timed_out (decision is a provisional review).
189
+ escalation:,
190
+ # Identifier of the policy.
191
+ policy_id:,
192
+ # Policy score between 0 and 1. Higher means more likely violating.
193
+ score:,
194
+ # Version of the policy.
195
+ version:
196
+ )
197
+ end
185
198
 
186
199
  sig do
187
200
  override.returns(
188
- T::Array[
189
- SafetyKit::Models::ContentCreateResponse::Escalation::TaggedSymbol
190
- ]
201
+ {
202
+ decision:
203
+ SafetyKit::Models::ContentCreateResponse::Policy::Decision::TaggedSymbol,
204
+ escalation:
205
+ SafetyKit::Models::ContentCreateResponse::Policy::Escalation::TaggedSymbol,
206
+ policy_id: String,
207
+ score: Float,
208
+ version: String
209
+ }
191
210
  )
192
211
  end
193
- def self.values
212
+ def to_hash
213
+ end
214
+
215
+ # Decision for the submitted content: match (violates the policy), not_match (does
216
+ # not violate), or review (needs human review).
217
+ module Decision
218
+ extend SafetyKit::Internal::Type::Enum
219
+
220
+ TaggedSymbol =
221
+ T.type_alias do
222
+ T.all(
223
+ Symbol,
224
+ SafetyKit::Models::ContentCreateResponse::Policy::Decision
225
+ )
226
+ end
227
+ OrSymbol = T.type_alias { T.any(Symbol, String) }
228
+
229
+ MATCH =
230
+ T.let(
231
+ :match,
232
+ SafetyKit::Models::ContentCreateResponse::Policy::Decision::TaggedSymbol
233
+ )
234
+ NOT_MATCH =
235
+ T.let(
236
+ :not_match,
237
+ SafetyKit::Models::ContentCreateResponse::Policy::Decision::TaggedSymbol
238
+ )
239
+ REVIEW =
240
+ T.let(
241
+ :review,
242
+ SafetyKit::Models::ContentCreateResponse::Policy::Decision::TaggedSymbol
243
+ )
244
+
245
+ sig do
246
+ override.returns(
247
+ T::Array[
248
+ SafetyKit::Models::ContentCreateResponse::Policy::Decision::TaggedSymbol
249
+ ]
250
+ )
251
+ end
252
+ def self.values
253
+ end
254
+ end
255
+
256
+ # Escalation outcome: none (no escalation ran), completed (verdict reflected in
257
+ # decision), or timed_out (decision is a provisional review).
258
+ module Escalation
259
+ extend SafetyKit::Internal::Type::Enum
260
+
261
+ TaggedSymbol =
262
+ T.type_alias do
263
+ T.all(
264
+ Symbol,
265
+ SafetyKit::Models::ContentCreateResponse::Policy::Escalation
266
+ )
267
+ end
268
+ OrSymbol = T.type_alias { T.any(Symbol, String) }
269
+
270
+ NONE =
271
+ T.let(
272
+ :none,
273
+ SafetyKit::Models::ContentCreateResponse::Policy::Escalation::TaggedSymbol
274
+ )
275
+ COMPLETED =
276
+ T.let(
277
+ :completed,
278
+ SafetyKit::Models::ContentCreateResponse::Policy::Escalation::TaggedSymbol
279
+ )
280
+ TIMED_OUT =
281
+ T.let(
282
+ :timed_out,
283
+ SafetyKit::Models::ContentCreateResponse::Policy::Escalation::TaggedSymbol
284
+ )
285
+
286
+ sig do
287
+ override.returns(
288
+ T::Array[
289
+ SafetyKit::Models::ContentCreateResponse::Policy::Escalation::TaggedSymbol
290
+ ]
291
+ )
292
+ end
293
+ def self.values
294
+ end
194
295
  end
195
296
  end
196
297
 
@@ -227,52 +328,6 @@ module SafetyKit
227
328
  def to_hash
228
329
  end
229
330
  end
230
-
231
- class Score < SafetyKit::Internal::Type::BaseModel
232
- OrHash =
233
- T.type_alias do
234
- T.any(
235
- SafetyKit::Models::ContentCreateResponse::Score,
236
- SafetyKit::Internal::AnyHash
237
- )
238
- end
239
-
240
- # Identifier of the classifier that produced this score.
241
- sig { returns(String) }
242
- attr_accessor :classifier_id
243
-
244
- # Classifier score between 0 and 1. Higher means more likely violating.
245
- sig { returns(Float) }
246
- attr_accessor :score
247
-
248
- # Version of the classifier that produced this score.
249
- sig { returns(String) }
250
- attr_accessor :version
251
-
252
- # Score produced by one classifier for the submitted content.
253
- sig do
254
- params(classifier_id: String, score: Float, version: String).returns(
255
- T.attached_class
256
- )
257
- end
258
- def self.new(
259
- # Identifier of the classifier that produced this score.
260
- classifier_id:,
261
- # Classifier score between 0 and 1. Higher means more likely violating.
262
- score:,
263
- # Version of the classifier that produced this score.
264
- version:
265
- )
266
- end
267
-
268
- sig do
269
- override.returns(
270
- { classifier_id: String, score: Float, version: String }
271
- )
272
- end
273
- def to_hash
274
- end
275
- end
276
331
  end
277
332
  end
278
333
  end
@@ -6,12 +6,11 @@ module SafetyKit
6
6
  # the response.
7
7
  class Content
8
8
  # Classify a piece of content synchronously. Send user-authored text, images, or
9
- # both, and receive a decision (approve, reject, or review) with classifier scores
10
- # and reference set matches in the response. The full request body must stay under
11
- # 6MB, which allows roughly 4.4MB of raw image bytes after base64 inflation.
9
+ # both, and receive per-policy results with an overall decision (match, not_match,
10
+ # or review) in the response. Requests have a maximum size of 6MB.
12
11
  sig do
13
12
  params(
14
- entity_id: String,
13
+ user_id: String,
15
14
  content_id: String,
16
15
  images: T::Array[String],
17
16
  metadata: T::Hash[Symbol, T.nilable(T.anything)],
@@ -20,21 +19,17 @@ module SafetyKit
20
19
  ).returns(SafetyKit::Models::ContentCreateResponse)
21
20
  end
22
21
  def create(
23
- # Your stable identifier for the entity this content belongs to, such as a user,
24
- # listing, or message thread.
25
- entity_id:,
26
- # Your identifier for this piece of content the same content_id you send on
27
- # /v1/events. When provided, the event this call records deduplicates against the
28
- # same upload posted through the events API, so sending both never double-counts
29
- # the content.
22
+ # Your stable identifier for the user this content belongs to.
23
+ user_id:,
24
+ # Your identifier for this content, matching the content_id sent on /v1/events.
25
+ # Prevents double-counting content submitted to both endpoints.
30
26
  content_id: nil,
31
27
  # Images to classify, each as base64-encoded image bytes, raw or as a data URI. At
32
- # most 4 images. The full request body must stay under 6MB, which allows roughly
33
- # 4.4MB of raw image bytes after base64 inflation.
28
+ # most 20 images, 5MB each.
34
29
  images: nil,
35
30
  # Additional product context for this content. At most 8KB when serialized.
36
31
  metadata: nil,
37
- # User-authored text to classify. At most 20000 characters.
32
+ # User-authored text to classify. At most 16000 characters.
38
33
  text: nil,
39
34
  request_options: {}
40
35
  )
@@ -2,7 +2,7 @@ module SafetyKit
2
2
  module Models
3
3
  type content_create_params =
4
4
  {
5
- entity_id: String,
5
+ user_id: String,
6
6
  content_id: String,
7
7
  images: ::Array[String],
8
8
  metadata: ::Hash[Symbol, top?],
@@ -14,7 +14,7 @@ module SafetyKit
14
14
  extend SafetyKit::Internal::Type::RequestParameters::Converter
15
15
  include SafetyKit::Internal::Type::RequestParameters
16
16
 
17
- attr_accessor entity_id: String
17
+ attr_accessor user_id: String
18
18
 
19
19
  attr_reader content_id: String?
20
20
 
@@ -33,7 +33,7 @@ module SafetyKit
33
33
  def text=: (String) -> String
34
34
 
35
35
  def initialize: (
36
- entity_id: String,
36
+ user_id: String,
37
37
  ?content_id: String,
38
38
  ?images: ::Array[String],
39
39
  ?metadata: ::Hash[Symbol, top?],
@@ -42,7 +42,7 @@ module SafetyKit
42
42
  ) -> void
43
43
 
44
44
  def to_hash: -> {
45
- entity_id: String,
45
+ user_id: String,
46
46
  content_id: String,
47
47
  images: ::Array[String],
48
48
  metadata: ::Hash[Symbol, top?],
@@ -4,11 +4,9 @@ module SafetyKit
4
4
  {
5
5
  content_id: String,
6
6
  decision: SafetyKit::Models::ContentCreateResponse::decision,
7
- entity_id: String,
8
- escalation: SafetyKit::Models::ContentCreateResponse::escalation,
9
- mirrored: bool,
7
+ policies: ::Array[SafetyKit::Models::ContentCreateResponse::Policy],
10
8
  reference_set_matches: ::Array[SafetyKit::Models::ContentCreateResponse::ReferenceSetMatch],
11
- scores: ::Array[SafetyKit::Models::ContentCreateResponse::Score]
9
+ user_id: String
12
10
  }
13
11
 
14
12
  class ContentCreateResponse < SafetyKit::Internal::Type::BaseModel
@@ -16,58 +14,99 @@ module SafetyKit
16
14
 
17
15
  attr_accessor decision: SafetyKit::Models::ContentCreateResponse::decision
18
16
 
19
- attr_accessor entity_id: String
20
-
21
- attr_accessor escalation: SafetyKit::Models::ContentCreateResponse::escalation
22
-
23
- attr_accessor mirrored: bool
17
+ attr_accessor policies: ::Array[SafetyKit::Models::ContentCreateResponse::Policy]
24
18
 
25
19
  attr_accessor reference_set_matches: ::Array[SafetyKit::Models::ContentCreateResponse::ReferenceSetMatch]
26
20
 
27
- attr_accessor scores: ::Array[SafetyKit::Models::ContentCreateResponse::Score]
21
+ attr_accessor user_id: String
28
22
 
29
23
  def initialize: (
30
24
  content_id: String,
31
25
  decision: SafetyKit::Models::ContentCreateResponse::decision,
32
- entity_id: String,
33
- escalation: SafetyKit::Models::ContentCreateResponse::escalation,
34
- mirrored: bool,
26
+ policies: ::Array[SafetyKit::Models::ContentCreateResponse::Policy],
35
27
  reference_set_matches: ::Array[SafetyKit::Models::ContentCreateResponse::ReferenceSetMatch],
36
- scores: ::Array[SafetyKit::Models::ContentCreateResponse::Score]
28
+ user_id: String
37
29
  ) -> void
38
30
 
39
31
  def to_hash: -> {
40
32
  content_id: String,
41
33
  decision: SafetyKit::Models::ContentCreateResponse::decision,
42
- entity_id: String,
43
- escalation: SafetyKit::Models::ContentCreateResponse::escalation,
44
- mirrored: bool,
34
+ policies: ::Array[SafetyKit::Models::ContentCreateResponse::Policy],
45
35
  reference_set_matches: ::Array[SafetyKit::Models::ContentCreateResponse::ReferenceSetMatch],
46
- scores: ::Array[SafetyKit::Models::ContentCreateResponse::Score]
36
+ user_id: String
47
37
  }
48
38
 
49
- type decision = :approve | :reject | :review
39
+ type decision = :match | :not_match | :review
50
40
 
51
41
  module Decision
52
42
  extend SafetyKit::Internal::Type::Enum
53
43
 
54
- APPROVE: :approve
55
- REJECT: :reject
44
+ MATCH: :match
45
+ NOT_MATCH: :not_match
56
46
  REVIEW: :review
57
47
 
58
48
  def self?.values: -> ::Array[SafetyKit::Models::ContentCreateResponse::decision]
59
49
  end
60
50
 
61
- type escalation = :none | :completed | :timed_out
51
+ type policy =
52
+ {
53
+ decision: SafetyKit::Models::ContentCreateResponse::Policy::decision,
54
+ escalation: SafetyKit::Models::ContentCreateResponse::Policy::escalation,
55
+ policy_id: String,
56
+ score: Float,
57
+ version: String
58
+ }
62
59
 
63
- module Escalation
64
- extend SafetyKit::Internal::Type::Enum
60
+ class Policy < SafetyKit::Internal::Type::BaseModel
61
+ attr_accessor decision: SafetyKit::Models::ContentCreateResponse::Policy::decision
62
+
63
+ attr_accessor escalation: SafetyKit::Models::ContentCreateResponse::Policy::escalation
64
+
65
+ attr_accessor policy_id: String
66
+
67
+ attr_accessor score: Float
68
+
69
+ attr_accessor version: String
70
+
71
+ def initialize: (
72
+ decision: SafetyKit::Models::ContentCreateResponse::Policy::decision,
73
+ escalation: SafetyKit::Models::ContentCreateResponse::Policy::escalation,
74
+ policy_id: String,
75
+ score: Float,
76
+ version: String
77
+ ) -> void
78
+
79
+ def to_hash: -> {
80
+ decision: SafetyKit::Models::ContentCreateResponse::Policy::decision,
81
+ escalation: SafetyKit::Models::ContentCreateResponse::Policy::escalation,
82
+ policy_id: String,
83
+ score: Float,
84
+ version: String
85
+ }
65
86
 
66
- NONE: :none
67
- COMPLETED: :completed
68
- TIMED_OUT: :timed_out
87
+ type decision = :match | :not_match | :review
69
88
 
70
- def self?.values: -> ::Array[SafetyKit::Models::ContentCreateResponse::escalation]
89
+ module Decision
90
+ extend SafetyKit::Internal::Type::Enum
91
+
92
+ MATCH: :match
93
+ NOT_MATCH: :not_match
94
+ REVIEW: :review
95
+
96
+ def self?.values: -> ::Array[SafetyKit::Models::ContentCreateResponse::Policy::decision]
97
+ end
98
+
99
+ type escalation = :none | :completed | :timed_out
100
+
101
+ module Escalation
102
+ extend SafetyKit::Internal::Type::Enum
103
+
104
+ NONE: :none
105
+ COMPLETED: :completed
106
+ TIMED_OUT: :timed_out
107
+
108
+ def self?.values: -> ::Array[SafetyKit::Models::ContentCreateResponse::Policy::escalation]
109
+ end
71
110
  end
72
111
 
73
112
  type reference_set_match = { set_id: String, similarity: Float }
@@ -81,24 +120,6 @@ module SafetyKit
81
120
 
82
121
  def to_hash: -> { set_id: String, similarity: Float }
83
122
  end
84
-
85
- type score = { classifier_id: String, score: Float, version: String }
86
-
87
- class Score < SafetyKit::Internal::Type::BaseModel
88
- attr_accessor classifier_id: String
89
-
90
- attr_accessor score: Float
91
-
92
- attr_accessor version: String
93
-
94
- def initialize: (
95
- classifier_id: String,
96
- score: Float,
97
- version: String
98
- ) -> void
99
-
100
- def to_hash: -> { classifier_id: String, score: Float, version: String }
101
- end
102
123
  end
103
124
  end
104
125
  end
@@ -2,7 +2,7 @@ module SafetyKit
2
2
  module Resources
3
3
  class Content
4
4
  def create: (
5
- entity_id: String,
5
+ user_id: String,
6
6
  ?content_id: String,
7
7
  ?images: ::Array[String],
8
8
  ?metadata: ::Hash[Symbol, top?],
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: safetykit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.51.0
4
+ version: 0.53.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Safetykit
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-08-05 00:00:00.000000000 Z
11
+ date: 2026-08-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cgi