Skip to main content
The biggest change isn’t a field rename — it’s scope. In v2, a “user” was a heavyweight object that bundled identity, KYC data, and wallet addresses all in one record, created and updated in one call. In v3, a user is a thin identity/status record; KYC, wallets, and everything else are separate resources you create afterward. See the platform-wide changes for ID format, pagination, error shape, and idempotency — this page only covers what’s specific to Users.
If you’re migrating, expect to split any v2 “create user” call into several v3 calls: create the bare user, then submit compliance/KYC data, then provision a wallet — instead of one call that did all three.

Endpoints

ToS link endpoints (POST /tos-link, GET /tos-link/:signedAgreementId, POST /tos-link/:signedAgreementId/accept) are unchanged in path and shape between v2 and v3.

Request changes: create a user

v2 accepted a large, open-ended body — identity/KYC fields, chains to provision wallets on, isDeveloper, and unknown fields were silently ignored:
v3 is a closed schema — only these fields are accepted, and anything else (firstName, email, chains, etc.) is rejected outright rather than ignored:
There’s no v3 update-user endpoint. If your v2 integration calls POST /v2/users/:userId to correct or add identity fields after creation, there’s no direct v3 replacement on the Users resource — that data now lives on the compliance/KYC side.

Response changes

v2 (GET /v2/users/:userId):
v3 (GET /v3/users/:userId):
v2 itself was inconsistent here — GET /v2/users/:userId included createdAt, but POST/create-or-update responses on the same v2 resource did not. v3 is consistent across create, get, and list.
List (GET /users): v2 returned { count, users: [...], nextCursor } where nextCursor was a raw ISO timestamp string. v3 returns the standard { data: [...], pagination: { hasMore, startCursor, endCursor } } — see platform-wide changes. There’s no count field in the v3 list response.