What’s new in v2
- One-step auth.
X-API-Keyissued from Compliance settings — no DevTools-extracted session token, no separate OAuth token endpoint, no 1-hour token rotation. - Single REST surface. Every operation is
GET/POST /v2/team.user.*with a unified{ok, request_id, ...}envelope. Connect RPC is also available at/team.v2.TeamUserManagementApiV2Service/<Method>. - Profile delegation. delegate / reclaim / rename / remove lets an active member take over a deactivated colleague’s data.
- Stable identifier. Every team member has a
team_user_idyou can cache; safer thanemailfor delegated profiles whose email is rewritten to a syntheticdelegate-<id>@...address. - Filters.
status_filteranddelegation_stateon team.user.list. - Server-side validation. Email format, length limits, and enum membership are enforced at the wire level via protovalidate; bad inputs fail fast with
invalid_argument.
Authentication
v1 used a two-step credential dance (session token → CreateApiCredential →client_id + client_secret → OAuth token endpoint → 1-hour Bearer access token). v2 collapses this to a single header.
See v2 Authentication for the full flow.
Endpoint mapping
Field naming and enums
Wire format. v1 uses camelCase (userName, firstName, lastName); v2 uses snake_case (user_name, first_name, last_name).
Role.
free_tier_member was renamed to GUEST in v2 to drop billing-internal jargon. Same semantics — does not consume a paid Stripe seat. Promoting GUEST → MEMBER/ADMIN/SUPER_ADMIN triggers a Stripe seat-quantity bump in both v1 and v2.
Status.
v2 adds
USER_STATUS_REMOVED which behaves like calling team.user.remove — hard-deletes the user and cascades reclaim of any profiles delegated to them.
User response shape.
Response envelope
v1 returns the payload directly. v2 wraps every response in{ok, request_id, ...}.
Error code mapping
Migration checklist
1
Issue a v2 API key
Create a Team User Management key in Compliance settings. Copy it immediately — it is shown only once. See v2 Authentication.
2
Pilot a read-only call against v2
v1 and v2 hit the same backing tables, so you can exercise team.user.list against your live team without affecting v1 traffic. Confirm field names, role/status enum values, and pagination behavior.
3
Rewrite request bodies
Convert camelCase → snake_case (
userName → user_name, etc.). Replace role/status string literals with the new enum constants. Move identifiers from path to body for team.user.update.4
Adopt the response envelope
Read
ok / error instead of relying on HTTP status codes alone. Persist request_id in your logs to make support requests actionable.5
Cache `team_user_id`
Whenever you create a member or list members, store the returned
team_user_id. Use it for subsequent updates — it survives renames and delegation, unlike email.6
Cut over and revoke v1 credentials
Once your integration is fully on v2, delete the old
client_id / client_secret via team.credential.delete so the v1 OAuth surface can no longer be used by stale callers.What stays the same
- Pagination defaults (
limit100, max 1000;offset0-based) - Owner is read-only via API
- Auto-provisioning of personal accounts during create
- All operations are audit-logged
- The Stripe seat-sync behavior on guest↔paid promotions
SailPoint / Okta connector notes
If your IDP connector is wired against v1, the migration is mostly:- Swap the Token URL (
/api/user/manage/v1/oauth/token) for anX-API-Keystatic header — no token endpoint to call. - Update endpoint paths and method for update (PATCH → POST).
- Remap attribute paths under
users[](camelCase → snake_case) and any role/status string lookups to the new enum constants. - Optionally map
team_user_idas a secondary identifier alongsideemailso account aggregation continues to work for delegated profiles.