Skip to main content
v3 have these new separate resources: Compliance Profile (this page — identity fields), Associated Party (beneficial owners/directors), Documents, and Questionnaire (new — source-of-funds style Q&A). See the platform-wide changes for ID format, pagination, error shape, and idempotency.
Existing v2 users: identity data only carries over to v3 if the user’s v2 KYC was actually submitted (POST /v2/users/:userId/kyc/submissions). For a v2 user who was created but never submitted KYC, there’s nothing to backfill — GET /v3/users/:userId/compliance/profile and the Associated Party endpoints return empty until you submit their data fresh in v3.

Major change: compliance is now rail-agnostic

In v2, KYC access was tracked per railUSD, GLOBAL_NETWORK, AFRICA_GENERAL, and others each had their own field requirements and their own status. A user could be ACTIVE on one rail and still need a separate submission — sometimes with different required fields — to unlock another. Adding a new corridor to your integration could mean re-submitting KYC for that rail specifically. v3 has no rail concept anywhere in Compliance. There’s one identity submission and one aggregate complianceStatus per user. Once a Compliance Profile is submitted and approved, HIFI automatically resolves which corridors that user is eligible for based on their profile (country, business type, etc.) and unlocks access accordingly — you don’t call anything rail- or provider-specific to “activate” a corridor. If you later want to offramp through a new corridor that user’s profile already qualifies them for, there’s no additional KYC step; access is already there.

Endpoints

Request changes

Both versions accept identity fields directly on the same object as the rest of KYC in v2; in v3 the same fields move to the standalone Compliance Profile, split cleanly by type. In both cases beneficial owners, documents, and Q&A are no longer part of this payload — submit them separately via Associated Party, Documents, and Questionnaire.

Individual (KYC)

v2:
v3:

Business (KYB)

v2:
v3:

Status changes

v2 tracked status per rail — a user could simultaneously be COMPLETED on one rail and PENDING on another (GET /kyc/status could return a status per rail, or the whole map). Status enum: CREATED, ACTIVE, INACTIVE, PENDING, COMPLETED, ON_HOLD, RFI_PENDING, INCOMPLETE, REJECTED, MANUAL_REVIEW, CONTACT_SUPPORT. v3 returns one aggregate status for the user, derived from the underlying compliance review, plus a structured list of exactly what’s blocking approval:
Status enum: NOT_SUBMITTED, PENDING, IN_REVIEW, APPROVED, REJECTED, REQUIRES_INFO. rfiActions points at exactly which sub-resource needs attention (a specific document, associated party, or profile field) — v2 had no equivalent structured “what’s wrong” list.

New in v3: rfiActions

v2 had no structured way to tell you why a RFI_PENDING status was set — you’d get the status and had to contact support or guess. In v3, whenever complianceStatus is REQUIRES_INFO, rfiActions on GET /v3/users/:userId/compliance/status returns a typed, machine-readable list of exactly what needs to change before resubmission:
Once you’ve addressed every action in the list, call POST /v3/users/:userId/compliance/submit again — there’s no per-action resubmission endpoint, the whole package goes back for review.
For business user, if the object contain associatedPartyId it means the resouce of the respective associated party needs additional action
Poll GET /v3/users/:userId/compliance/status or listen for the compliance status webhook to catch a transition to REQUIRES_INFO — don’t rely on rfiActions being populated at any other status.

ID format

The user’s Compliance Profile isn’t independently addressable by its own ID — it’s fetched/updated via the user’s ID (GET/PATCH /users/:userId/compliance/profile), same as v2.