Skip to content

Add support for the Global Profile API - #164

Open
tholovina-sift wants to merge 3 commits into
masterfrom
atlas-382-global-profile-api
Open

Add support for the Global Profile API#164
tholovina-sift wants to merge 3 commits into
masterfrom
atlas-382-global-profile-api

Conversation

@tholovina-sift

@tholovina-sift tholovina-sift commented Aug 18, 2026

Copy link
Copy Markdown

Purpose:

  • Add client support for the new Global Profile API, which returns cross-tenant identity, decision, chargeback, order, transaction, and location signals for a user
  • Expose two new endpoints: GET /v3/accounts/{accountId}/global_profile/users/{userId} (lookup by Sift user ID) and POST /v3/accounts/{accountId}/global_profile/lookup (lookup by email and/or phone)

Technical overview:

  • GlobalProfileFieldSet / GlobalProfileRequest / GlobalProfileResponse — GET endpoint following the GetDecisionsRequest query-parameter pattern; optional globalOnly and includeOwnData params are only sent when explicitly set
  • GlobalProfileLookupFieldSet / GlobalProfileLookupRequest / GlobalProfileLookupResponse — POST endpoint; overrides validate() (same pattern as ApplyDecisionFieldSet) to throw MissingFieldException client-side when neither email nor phone is provided
  • GlobalProfileResponseBody shared between both endpoints, with nested model classes for all response fields (GlobalProfileSummary, GlobalProfileIdentityAge, GlobalProfileUserDecisions, GlobalProfileChargebacks, GlobalProfileOrders, GlobalProfileTransactions, GlobalProfileLocations, GlobalProfileLocationAccount); all fields use @Expose / @SerializedName Gson convention
  • SiftClient gains two new buildRequest(...) overloads, matching the existing dispatch-by-type convention
  • When profile_summary.identity_found is false, all fields except profile_summary are null, as documented on GlobalProfileResponseBody

Testing plan:

  • This PR contains all required labels and reviewers as per our Change Management Procedure

  • Live tested against the Sift API with a real account: both GET and POST returned status=0, error_message=OK with identity_found=true, link_count=31, and fully populated location entries including city, region, and country

Deployment plan:

  • Related documentation is updated

    • README.md: new "Global Profile API" section with usage examples for both endpoints
    • CHANGES.MD: new 3.23.0 entry
    • build.gradle: version bumped to 3.23.0
  • Merge when Global Profile API is publicly available

  • Merge before https://github.com/SiftScience/sift-docs/pull/92

Rollback plan:

  • Revert this PR; no schema changes, no breaking changes to existing methods, fully additive

Customer Impact Assessment:

tholovina-sift and others added 3 commits August 18, 2026 21:34
Co-Authored-By: Claude <noreply@anthropic.com>
- Add validate() to GlobalProfileFieldSet throwing MissingFieldException when userId is null/empty (P1)
- Type GlobalProfileRequest constructor parameter as GlobalProfileFieldSet instead of raw FieldSet (P2)
- Add @Expose/@SerializedName to GlobalProfileFieldSet fields so fromJson() deserializes correctly (P3)
- Capture return value and add is_ok()/identity_found assertions to testGlobalProfileLookupByPhone (P4)
- Add testLookupIdentityNotFound covering the identity_found=false Lookup response path (P5)
- Add assertNull assertions for chargebacks/orders/transactions/locations/lookbackMonths in testIdentityNotFound (P6)
- Add Authorization header assertion to testGetGlobalProfileWithoutOptionalParams (P7)
- Fix pre-existing test failures: remove null-valued fields from JSONAssert comparison bodies so they match toJson() output (Gson omits nulls by default)

Co-Authored-By: Claude <noreply@anthropic.com>
Server returns city, region, and country in location_connected_accounts
entries. The region field was absent, causing it to be silently dropped
on deserialization. Confirmed live via API test.

Co-Authored-By: Claude <noreply@anthropic.com>
@tholovina-sift
tholovina-sift marked this pull request as ready for review August 20, 2026 15:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant