Skip to main content
Questions or issues? Contact us at api-support@manus.ai. v2 supersedes the v1 Team User Management surface. v1 is not removed — existing integrations keep working — but new integrations should target v2 directly, and existing ones benefit from a smaller blast radius for credential management, a unified response envelope, the profile-delegation workflow, and stronger field validation.

What’s new in v2

  • One-step auth. X-API-Key issued 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_id you can cache; safer than email for delegated profiles whose email is rewritten to a synthetic delegate-<id>@... address.
  • Filters. status_filter and delegation_state on 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 (userNameuser_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 (limit 100, max 1000; offset 0-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:
  1. Swap the Token URL (/api/user/manage/v1/oauth/token) for an X-API-Key static header — no token endpoint to call.
  2. Update endpoint paths and method for update (PATCH → POST).
  3. Remap attribute paths under users[] (camelCase → snake_case) and any role/status string lookups to the new enum constants.
  4. Optionally map team_user_id as a secondary identifier alongside email so account aggregation continues to work for delegated profiles.