Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions HISTORY
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
=== 4.7.0 2026-08-27
- Added support for $nationality, $year_of_birth fields on $create_account, $update_account events
- Added support for $kyc field on $create_account, $update_account, $transaction, $create_order, $update_order, $verification events
- Added support for $geo, $bot_identification fields on $create_account, $update_account, $login, $transaction, $create_order, $update_order events

=== 4.6.0 2026-02-10
- Bump the minimum version of httparty to 0.23.3 to ensure protection against CVE-2025-68696
- Refactor Client to use dedicated internal HTTP clients for different API endpoints
Expand Down
71 changes: 71 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,77 @@ response.api_error_message # Error message associated with status Error Code
response = client.score(user_id)
```

### New KYC Signals, Geo & Bot Detection

```ruby
# $verification event with KYC outcome
response = client.track("$verification", {
"$user_id" => "23056",
"$verification_type" => "$kyc",
"$status" => "$success",
"$kyc" => {
"$names_match" => true,
"$kyc_level" => "$basic",
"$bin_nationality_match" => false,
"$provider" => "lexisnexis"
}
})

# $create_account with account-level identity attributes
response = client.track("$create_account", {
"$user_id" => "23056",
"$nationality" => "US",
"$year_of_birth" => 1985,
"$kyc" => {
"$names_match" => true,
"$kyc_level" => "$full",
"$provider" => "prove"
},
"$geo" => {
"$uuid" => "gc-abc-123",
"$provider" => "geocomply"
},
"$bot_identification" => {
"$result" => "$human",
"$provider" => "datadome"
}
})

# $login event with geo and bot-detection signals
response = client.track("$login", {
"$user_id" => "23056",
"$login_status" => "$success",
"$geo" => {
"$uuid" => "gc-abc-123",
"$provider" => "geocomply"
},
"$bot_identification" => {
"$result" => "$human",
"$provider" => "datadome"
}
})

# $transaction event with KYC, geo, and bot-detection signals
response = client.track("$transaction", {
"$user_id" => "23056",
"$amount" => 15230000,
"$currency_code" => "USD",
"$kyc" => {
"$names_match" => true,
"$bin_nationality_match" => true,
"$provider" => "lexisnexis"
},
"$geo" => {
"$uuid" => "gc-abc-123",
"$provider" => "geocomply"
},
"$bot_identification" => {
"$result" => "$suspected",
"$provider" => "human_security"
}
})
```

## Decisions

To learn more about the decisions endpoint visit our [developer docs](https://sift.com/developers/docs/ruby/decisions-api/get-decisions).
Expand Down
2 changes: 1 addition & 1 deletion lib/sift/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module Sift
VERSION = "4.6.0"
VERSION = "4.7.0"
API_VERSION = "205"
VERIFICATION_API_VERSION = "1.1"
end
60 changes: 60 additions & 0 deletions spec/unit/client_structured_fields_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
require_relative '../spec_helper'
require 'sift'

describe Sift::Client do

before :each do
Sift.api_key = nil
end

it "Successfully submits a $create_account event with KYC, geo, and bot-detection structured fields" do
response_json = { :status => 0, :error_message => "OK" }
stub_request(:post, "https://api.siftscience.com/v205/events").
with { |request|
parsed_body = JSON.parse(request.body)
expect(parsed_body["$nationality"]).to eq("US")
expect(parsed_body["$year_of_birth"]).to eq(1985)
expect(parsed_body["$kyc"]).to eq({
"$names_match" => true,
"$kyc_level" => "$basic",
"$bin_nationality_match" => true,
"$provider" => "lexisnexis"
})
expect(parsed_body["$geo"]).to eq({
"$uuid" => "gc-abc-123",
"$provider" => "geocomply"
})
expect(parsed_body["$bot_identification"]).to eq({
"$result" => "$human",
"$provider" => "datadome"
})
}.to_return(:status => 200, :body => MultiJson.dump(response_json), :headers => {})

api_key = "foobar"
properties = {
:$type => "$create_account",
:$user_id => "23056",
:$nationality => "US",
:$year_of_birth => 1985,
:$kyc => {
:$names_match => true,
:$kyc_level => "$basic",
:$bin_nationality_match => true,
:$provider => "lexisnexis"
},
:$geo => {
:$uuid => "gc-abc-123",
:$provider => "geocomply"
},
:$bot_identification => {
:$result => "$human",
:$provider => "datadome"
}
}

response = Sift::Client.new(:api_key => api_key, :version => "205")
.track("$create_account", properties)
expect(response.ok?).to eq(true)
expect(response.api_status).to eq(0)
end
end
121 changes: 109 additions & 12 deletions test_integration_app/events_api/test_events_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,17 @@ def login()
"$brand_name" => "sift",
"$site_domain" => "sift.com",
"$site_country" => "US",


# Structured fields (geo / bot detection)
Comment thread
rkumar-sift marked this conversation as resolved.
Outdated
"$geo" => {
"$uuid" => "gc-abc-123",
"$provider" => "geocomply"
},
"$bot_identification" => {
"$result" => "$human",
"$provider" => "datadome"
},

# Send this information with a login from a BROWSER client.
"$browser" => {
"$user_agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
Expand Down Expand Up @@ -107,21 +117,36 @@ def transaction()

# For marketplaces, use $seller_user_id to identify the seller
"$seller_user_id" => "slinkys_emporium",


# Structured fields (KYC / geo / bot detection)
"$kyc" => {
"$names_match" => true,
"$bin_nationality_match" => false,
"$provider" => "prove"
},
"$geo" => {
"$uuid" => "gc-abc-123",
"$provider" => "geocomply"
},
"$bot_identification" => {
"$result" => "$human",
"$provider" => "human_security"
},

# Sample Custom Fields
"digital_wallet" => "apple_pay", # "google_wallet", etc.
"coupon_code" => "dollarMadness",
"shipping_choice" => "FedEx Ground Courier",
"is_first_time_buyer" => false,

# Send this information from a BROWSER client.
"$browser" => {
"$user_agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"$accept_language" => "en-US",
"$content_language" => "en-GB"
}
}

return @@client.track("$transaction", properties, :warnings => 'true')
end

Expand Down Expand Up @@ -233,15 +258,30 @@ def create_order()
"coupon_code" => "dollarMadness",
"shipping_choice" => "FedEx Ground Courier",
"is_first_time_buyer" => false,


# Structured fields (KYC / geo / bot detection)
"$kyc" => {
"$names_match" => true,
"$kyc_level" => "$basic",
"$provider" => "lexisnexis"
},
"$geo" => {
"$uuid" => "gc-abc-123",
"$provider" => "geocomply"
},
"$bot_identification" => {
"$result" => "$human",
"$provider" => "datadome"
},

# Send this information from a BROWSER client.
"$browser" => {
"$user_agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"$accept_language" => "en-US",
"$content_language" => "en-GB"
}
}

return @@client.track("$create_order", properties)
end

Expand Down Expand Up @@ -457,15 +497,32 @@ def update_account()

"$social_sign_on_type" => "$twitter",
"$account_types" => ["merchant", "premium"],


# Structured fields (KYC / geo / bot detection)
"$nationality" => "US",
"$year_of_birth" => 1985,
"$kyc" => {
"$names_match" => true,
"$kyc_level" => "$full",
"$provider" => "prove"
},
"$geo" => {
"$uuid" => "gc-abc-123",
"$provider" => "geocomply"
},
"$bot_identification" => {
"$result" => "$human",
"$provider" => "datadome"
},

# Send this information from a BROWSER client.
"$browser" => {
"$user_agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"$accept_language" => "en-US",
"$content_language" => "en-GB"
}
}

return @@client.track("$update_account", properties)
end

Expand Down Expand Up @@ -585,7 +642,24 @@ def create_account()

"$social_sign_on_type" => "$twitter",
"$account_types" => ["merchant", "premium"],


# Structured fields (KYC / geo / bot detection)
"$nationality" => "US",
"$year_of_birth" => 1985,
"$kyc" => {
"$names_match" => true,
"$kyc_level" => "$basic",
"$provider" => "lexisnexis"
},
"$geo" => {
"$uuid" => "gc-abc-123",
"$provider" => "geocomply"
},
"$bot_identification" => {
"$result" => "$human",
"$provider" => "datadome"
},

# Suggested Custom Fields
"twitter_handle" => "billyjones",
"work_phone" => "1-347-555-5921",
Expand Down Expand Up @@ -618,7 +692,15 @@ def verification()
"$verified_event" => "$login",
"$reason" => "$automated_rule", # Verification was triggered based on risk score
"$verification_type" => "$sms",
"$verified_value" => "14155551212"
"$verified_value" => "14155551212",

# Structured fields (KYC)
"$kyc" => {
"$names_match" => true,
"$kyc_level" => "$basic",
"$bin_nationality_match" => false,
"$provider" => "lexisnexis"
}
}

return @@client.track("$verification", properties)
Expand Down Expand Up @@ -828,15 +910,30 @@ def update_order()
"coupon_code" => "dollarMadness",
"shipping_choice" => "FedEx Ground Courier",
"is_first_time_buyer" => false,


# Structured fields (KYC / geo / bot detection)
"$kyc" => {
"$names_match" => true,
"$kyc_level" => "$basic",
"$provider" => "lexisnexis"
},
"$geo" => {
"$uuid" => "gc-abc-123",
"$provider" => "geocomply"
},
"$bot_identification" => {
"$result" => "$human",
"$provider" => "datadome"
},

# Send this information from a BROWSER client.
"$browser" => {
"$user_agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"$accept_language" => "en-US",
"$content_language" => "en-GB"
}
}

return @@client.track("$update_order", properties)
end

Expand Down
Loading