from __future__ import annotations

from typing import Dict, List, Union, Optional
from datetime import datetime
from itertools import chain
from typing_extensions import Literal

import httpx2

from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
from ..._utils import is_given, path_template, strip_not_given
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import (
    to_raw_response_wrapper,
    to_streamed_response_wrapper,
    async_to_raw_response_wrapper,
    async_to_streamed_response_wrapper,
)
from ...pagination import SyncPageCursor, AsyncPageCursor
from ...types.beta import (
    BetaUserProfileExternalUserDetailsParams,
)
from ..._base_client import AsyncPaginator, make_request_options
from ...types.anthropic_beta_param import AnthropicBetaParam
from ...types.beta.beta_user_profile import BetaUserProfile
from ...types.beta.beta_user_profile_enrollment_url import BetaUserProfileEnrollmentURL
from ...types.beta.beta_user_profile_external_user_details_params import BetaUserProfileExternalUserDetailsParams

__all__ = ["UserProfiles", "AsyncUserProfiles"]


class UserProfiles(SyncAPIResource):
    @cached_property
    def with_raw_response(self) -> UserProfilesWithRawResponse:
        """
        This property can be used as a prefix for any HTTP method call to return
        the raw response object instead of the parsed content.

        For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers
        """
        return UserProfilesWithRawResponse(self)

    @cached_property
    def with_streaming_response(self) -> UserProfilesWithStreamingResponse:
        """
        An alternative to `.with_raw_response` that doesn't eagerly read the response body.

        For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response
        """
        return UserProfilesWithStreamingResponse(self)

    def create(
        self,
        *,
        access_type: Literal["application", "passthrough"] | Omit = omit,
        external_id: Optional[str] | Omit = omit,
        external_user_details: BetaUserProfileExternalUserDetailsParams | Omit = omit,
        external_user_onboarded_at: Union[str, datetime] | Omit = omit,
        metadata: Dict[str, str] | Omit = omit,
        name: Optional[str] | Omit = omit,
        betas: List[AnthropicBetaParam] | Omit = omit,
        workspace_id: str | Omit = omit,
        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
        # The extra values given here take precedence over values defined on the client or passed to this method.
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: float | httpx2.Timeout | None | NotGiven = not_given,
    ) -> BetaUserProfile:
        """
        Create User Profile

        Args:
          access_type: How the platform uses the API on behalf of the entity this profile represents.
              `application`: the platform sells a product that uses the API behind the scenes,
              and the profile represents an individual end-user of that product.
              `passthrough`: the platform resells raw inference, and the profile identifies
              the resold-to company.

              - `application` - The user profile represents an individual end-user of a
                product that the platform builds on the API. New profiles get this value by
                default.
              - `passthrough` - The user profile represents a company that the platform
                resells Claude access to.

          external_id: Platform's own identifier for this user. Not enforced unique. Maximum 255
              characters. Accepted under the `user-profiles-2026-03-24` and
              `user-profiles-2026-08-18` beta headers; under `user-profiles-2026-09-04` send
              `external_user_details.reference_id` instead.

          external_user_details: Details about the entity this profile represents, as the platform states them.
              Every field is optional. Accepted under the `user-profiles-2026-09-04` beta
              header only.

          external_user_onboarded_at: A timestamp in RFC 3339 format

          metadata: Free-form key-value data to attach to this user profile. Maximum 16 keys, with
              keys up to 64 characters and values up to 512 characters. Values must be
              non-empty strings.

          name: Optional for all profiles. Real-world name of the entity this profile represents
              (company or individual); for a company the platform resells Claude access to
              (`access_type` `passthrough`), that company's name where known. Maximum 255
              characters.

          betas: Optional header to specify the beta version(s) you want to use.

          workspace_id: Optional header to select the Workspace for this request. The value is a
              Workspace ID (for example, `wrkspc_011CZkZaBF1tNoB5wlCeusgy`).

              Only needed for credentials that can act on more than one Workspace. A
              credential that belongs to a specific Workspace may omit it; if sent, it must
              match that Workspace.

          extra_headers: Send extra headers

          extra_query: Add additional query parameters to the request

          extra_body: Add additional JSON properties to the request

          timeout: Override the client-level default timeout for this request, in seconds
        """
        extra_headers = {
            **strip_not_given(
                {
                    "anthropic-beta": ",".join(chain((str(e) for e in betas), ["user-profiles-2026-08-18"]))
                    if is_given(betas)
                    else not_given,
                    "anthropic-workspace-id": workspace_id,
                }
            ),
            **(extra_headers or {}),
        }
        extra_headers = {"anthropic-beta": "user-profiles-2026-08-18", **(extra_headers or {})}
        return self._post(
            "/v1/user_profiles?beta=true",
            body={
                "access_type": access_type,
                "external_id": external_id,
                "external_user_details": external_user_details,
                "external_user_onboarded_at": external_user_onboarded_at,
                "metadata": metadata,
                "name": name,
            },
            options=make_request_options(
                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
            ),
            cast_to=BetaUserProfile,
        )

    def retrieve(
        self,
        user_profile_id: str,
        *,
        betas: List[AnthropicBetaParam] | Omit = omit,
        workspace_id: str | Omit = omit,
        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
        # The extra values given here take precedence over values defined on the client or passed to this method.
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: float | httpx2.Timeout | None | NotGiven = not_given,
    ) -> BetaUserProfile:
        """
        Get User Profile

        Args:
          user_profile_id: The ID of the user profile to get (`uprof_...`).

          betas: Optional header to specify the beta version(s) you want to use.

          workspace_id: Optional header to select the Workspace for this request. The value is a
              Workspace ID (for example, `wrkspc_011CZkZaBF1tNoB5wlCeusgy`).

              Only needed for credentials that can act on more than one Workspace. A
              credential that belongs to a specific Workspace may omit it; if sent, it must
              match that Workspace.

          extra_headers: Send extra headers

          extra_query: Add additional query parameters to the request

          extra_body: Add additional JSON properties to the request

          timeout: Override the client-level default timeout for this request, in seconds
        """
        if not user_profile_id:
            raise ValueError(f"Expected a non-empty value for `user_profile_id` but received {user_profile_id!r}")
        extra_headers = {
            **strip_not_given(
                {
                    "anthropic-beta": ",".join(chain((str(e) for e in betas), ["user-profiles-2026-08-18"]))
                    if is_given(betas)
                    else not_given,
                    "anthropic-workspace-id": workspace_id,
                }
            ),
            **(extra_headers or {}),
        }
        extra_headers = {"anthropic-beta": "user-profiles-2026-08-18", **(extra_headers or {})}
        return self._get(
            path_template("/v1/user_profiles/{user_profile_id}?beta=true", user_profile_id=user_profile_id),
            options=make_request_options(
                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
            ),
            cast_to=BetaUserProfile,
        )

    def update(
        self,
        user_profile_id: str,
        *,
        access_type: Optional[Literal["application", "passthrough"]] | Omit = omit,
        external_id: Optional[str] | Omit = omit,
        external_user_details: BetaUserProfileExternalUserDetailsParams | Omit = omit,
        external_user_onboarded_at: Union[str, datetime] | Omit = omit,
        metadata: Dict[str, str] | Omit = omit,
        name: Optional[str] | Omit = omit,
        betas: List[AnthropicBetaParam] | Omit = omit,
        workspace_id: str | Omit = omit,
        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
        # The extra values given here take precedence over values defined on the client or passed to this method.
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: float | httpx2.Timeout | None | NotGiven = not_given,
    ) -> BetaUserProfile:
        """
        Update User Profile

        Args:
          user_profile_id: The ID of the user profile to update (`uprof_...`).

          access_type: How the platform uses the API on behalf of the entity this profile represents.
              `application`: the platform sells a product that uses the API behind the scenes,
              and the profile represents an individual end-user of that product.
              `passthrough`: the platform resells raw inference, and the profile identifies
              the resold-to company.

              - `application` - The user profile represents an individual end-user of a
                product that the platform builds on the API. New profiles get this value by
                default.
              - `passthrough` - The user profile represents a company that the platform
                resells Claude access to.

          external_id: If present, replaces the stored external_id. Omit to leave unchanged. Maximum
              255 characters. Accepted under the `user-profiles-2026-03-24` and
              `user-profiles-2026-08-18` beta headers; under `user-profiles-2026-09-04` send
              `external_user_details.reference_id` instead.

          external_user_details: Details about the entity this profile represents, as the platform states them.
              Each field sent replaces the stored value; omit a field to leave it unchanged.
              Once set, a value cannot be cleared and `null` is rejected. Accepted under the
              `user-profiles-2026-09-04` beta header only.

          external_user_onboarded_at: A timestamp in RFC 3339 format

          metadata: Key-value pairs to merge into the stored metadata. Keys provided overwrite
              existing values. To remove a key, set its value to an empty string. Keys not
              provided are left unchanged. Maximum 16 keys, with keys up to 64 characters and
              values up to 512 characters.

          name: If present, replaces the stored name. Omit to leave unchanged. Maximum 255
              characters.

          betas: Optional header to specify the beta version(s) you want to use.

          workspace_id: Optional header to select the Workspace for this request. The value is a
              Workspace ID (for example, `wrkspc_011CZkZaBF1tNoB5wlCeusgy`).

              Only needed for credentials that can act on more than one Workspace. A
              credential that belongs to a specific Workspace may omit it; if sent, it must
              match that Workspace.

          extra_headers: Send extra headers

          extra_query: Add additional query parameters to the request

          extra_body: Add additional JSON properties to the request

          timeout: Override the client-level default timeout for this request, in seconds
        """
        if not user_profile_id:
            raise ValueError(f"Expected a non-empty value for `user_profile_id` but received {user_profile_id!r}")
        extra_headers = {
            **strip_not_given(
                {
                    "anthropic-beta": ",".join(chain((str(e) for e in betas), ["user-profiles-2026-08-18"]))
                    if is_given(betas)
                    else not_given,
                    "anthropic-workspace-id": workspace_id,
                }
            ),
            **(extra_headers or {}),
        }
        extra_headers = {"anthropic-beta": "user-profiles-2026-08-18", **(extra_headers or {})}
        return self._post(
            path_template("/v1/user_profiles/{user_profile_id}?beta=true", user_profile_id=user_profile_id),
            body={
                "access_type": access_type,
                "external_id": external_id,
                "external_user_details": external_user_details,
                "external_user_onboarded_at": external_user_onboarded_at,
                "metadata": metadata,
                "name": name,
            },
            options=make_request_options(
                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
            ),
            cast_to=BetaUserProfile,
        )

    def list(
        self,
        *,
        limit: int | Omit = omit,
        order: Literal["asc", "desc"] | Omit = omit,
        order_by: Literal["created_at", "name"] | Omit = omit,
        page: str | Omit = omit,
        betas: List[AnthropicBetaParam] | Omit = omit,
        workspace_id: str | Omit = omit,
        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
        # The extra values given here take precedence over values defined on the client or passed to this method.
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: float | httpx2.Timeout | None | NotGiven = not_given,
    ) -> SyncPageCursor[BetaUserProfile]:
        """
        List User Profiles

        Args:
          limit: The maximum number of user profiles to return, from 1 to 100. Defaults to 20.

          order: The sort direction, applied to the field that `order_by` selects. Defaults to
              `desc`.

              - `asc` - Oldest first when `order_by` is `created_at`, or names in ascending
                order when `order_by` is `name`.
              - `desc` - Newest first when `order_by` is `created_at`, or names in descending
                order when `order_by` is `name`. This is the default.

          order_by: The field to sort user profiles by, in the direction that `order` sets. Defaults
              to `created_at`.

              - `created_at` - Sort by when each user profile was created. This is the
                default.
              - `name` - Sort by `name`, ignoring the case of ASCII letters. Profiles without
                a name come last in either direction.

          page: The cursor for the page to return, taken from `next_page` in a previous
              response.

              Leave it out to get the first page.

          betas: Optional header to specify the beta version(s) you want to use.

          workspace_id: Optional header to select the Workspace for this request. The value is a
              Workspace ID (for example, `wrkspc_011CZkZaBF1tNoB5wlCeusgy`).

              Only needed for credentials that can act on more than one Workspace. A
              credential that belongs to a specific Workspace may omit it; if sent, it must
              match that Workspace.

          extra_headers: Send extra headers

          extra_query: Add additional query parameters to the request

          extra_body: Add additional JSON properties to the request

          timeout: Override the client-level default timeout for this request, in seconds
        """
        extra_headers = {
            **strip_not_given(
                {
                    "anthropic-beta": ",".join(chain((str(e) for e in betas), ["user-profiles-2026-08-18"]))
                    if is_given(betas)
                    else not_given,
                    "anthropic-workspace-id": workspace_id,
                }
            ),
            **(extra_headers or {}),
        }
        extra_headers = {"anthropic-beta": "user-profiles-2026-08-18", **(extra_headers or {})}
        return self._get_api_list(
            "/v1/user_profiles?beta=true",
            page=SyncPageCursor[BetaUserProfile],
            options=make_request_options(
                extra_headers=extra_headers,
                extra_query=extra_query,
                extra_body=extra_body,
                timeout=timeout,
                query={
                    "limit": limit,
                    "order": order,
                    "order_by": order_by,
                    "page": page,
                },
            ),
            model=BetaUserProfile,
        )

    def create_enrollment_url(
        self,
        user_profile_id: str,
        *,
        betas: List[AnthropicBetaParam] | Omit = omit,
        workspace_id: str | Omit = omit,
        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
        # The extra values given here take precedence over values defined on the client or passed to this method.
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: float | httpx2.Timeout | None | NotGiven = not_given,
    ) -> BetaUserProfileEnrollmentURL:
        """
        Create Enrollment URL

        Args:
          user_profile_id: The ID of the user profile to create an enrollment URL for (`uprof_...`).

          betas: Optional header to specify the beta version(s) you want to use.

          workspace_id: Optional header to select the Workspace for this request. The value is a
              Workspace ID (for example, `wrkspc_011CZkZaBF1tNoB5wlCeusgy`).

              Only needed for credentials that can act on more than one Workspace. A
              credential that belongs to a specific Workspace may omit it; if sent, it must
              match that Workspace.

          extra_headers: Send extra headers

          extra_query: Add additional query parameters to the request

          extra_body: Add additional JSON properties to the request

          timeout: Override the client-level default timeout for this request, in seconds
        """
        if not user_profile_id:
            raise ValueError(f"Expected a non-empty value for `user_profile_id` but received {user_profile_id!r}")
        extra_headers = {
            **strip_not_given(
                {
                    "anthropic-beta": ",".join(chain((str(e) for e in betas), ["user-profiles-2026-08-18"]))
                    if is_given(betas)
                    else not_given,
                    "anthropic-workspace-id": workspace_id,
                }
            ),
            **(extra_headers or {}),
        }
        extra_headers = {"anthropic-beta": "user-profiles-2026-08-18", **(extra_headers or {})}
        return self._post(
            path_template(
                "/v1/user_profiles/{user_profile_id}/enrollment_url?beta=true", user_profile_id=user_profile_id
            ),
            options=make_request_options(
                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
            ),
            cast_to=BetaUserProfileEnrollmentURL,
        )


class AsyncUserProfiles(AsyncAPIResource):
    @cached_property
    def with_raw_response(self) -> AsyncUserProfilesWithRawResponse:
        """
        This property can be used as a prefix for any HTTP method call to return
        the raw response object instead of the parsed content.

        For more information, see https://www.github.com/anthropics/anthropic-sdk-python#accessing-raw-response-data-eg-headers
        """
        return AsyncUserProfilesWithRawResponse(self)

    @cached_property
    def with_streaming_response(self) -> AsyncUserProfilesWithStreamingResponse:
        """
        An alternative to `.with_raw_response` that doesn't eagerly read the response body.

        For more information, see https://www.github.com/anthropics/anthropic-sdk-python#with_streaming_response
        """
        return AsyncUserProfilesWithStreamingResponse(self)

    async def create(
        self,
        *,
        access_type: Literal["application", "passthrough"] | Omit = omit,
        external_id: Optional[str] | Omit = omit,
        external_user_details: BetaUserProfileExternalUserDetailsParams | Omit = omit,
        external_user_onboarded_at: Union[str, datetime] | Omit = omit,
        metadata: Dict[str, str] | Omit = omit,
        name: Optional[str] | Omit = omit,
        betas: List[AnthropicBetaParam] | Omit = omit,
        workspace_id: str | Omit = omit,
        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
        # The extra values given here take precedence over values defined on the client or passed to this method.
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: float | httpx2.Timeout | None | NotGiven = not_given,
    ) -> BetaUserProfile:
        """
        Create User Profile

        Args:
          access_type: How the platform uses the API on behalf of the entity this profile represents.
              `application`: the platform sells a product that uses the API behind the scenes,
              and the profile represents an individual end-user of that product.
              `passthrough`: the platform resells raw inference, and the profile identifies
              the resold-to company.

              - `application` - The user profile represents an individual end-user of a
                product that the platform builds on the API. New profiles get this value by
                default.
              - `passthrough` - The user profile represents a company that the platform
                resells Claude access to.

          external_id: Platform's own identifier for this user. Not enforced unique. Maximum 255
              characters. Accepted under the `user-profiles-2026-03-24` and
              `user-profiles-2026-08-18` beta headers; under `user-profiles-2026-09-04` send
              `external_user_details.reference_id` instead.

          external_user_details: Details about the entity this profile represents, as the platform states them.
              Every field is optional. Accepted under the `user-profiles-2026-09-04` beta
              header only.

          external_user_onboarded_at: A timestamp in RFC 3339 format

          metadata: Free-form key-value data to attach to this user profile. Maximum 16 keys, with
              keys up to 64 characters and values up to 512 characters. Values must be
              non-empty strings.

          name: Optional for all profiles. Real-world name of the entity this profile represents
              (company or individual); for a company the platform resells Claude access to
              (`access_type` `passthrough`), that company's name where known. Maximum 255
              characters.

          betas: Optional header to specify the beta version(s) you want to use.

          workspace_id: Optional header to select the Workspace for this request. The value is a
              Workspace ID (for example, `wrkspc_011CZkZaBF1tNoB5wlCeusgy`).

              Only needed for credentials that can act on more than one Workspace. A
              credential that belongs to a specific Workspace may omit it; if sent, it must
              match that Workspace.

          extra_headers: Send extra headers

          extra_query: Add additional query parameters to the request

          extra_body: Add additional JSON properties to the request

          timeout: Override the client-level default timeout for this request, in seconds
        """
        extra_headers = {
            **strip_not_given(
                {
                    "anthropic-beta": ",".join(chain((str(e) for e in betas), ["user-profiles-2026-08-18"]))
                    if is_given(betas)
                    else not_given,
                    "anthropic-workspace-id": workspace_id,
                }
            ),
            **(extra_headers or {}),
        }
        extra_headers = {"anthropic-beta": "user-profiles-2026-08-18", **(extra_headers or {})}
        return await self._post(
            "/v1/user_profiles?beta=true",
            body={
                "access_type": access_type,
                "external_id": external_id,
                "external_user_details": external_user_details,
                "external_user_onboarded_at": external_user_onboarded_at,
                "metadata": metadata,
                "name": name,
            },
            options=make_request_options(
                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
            ),
            cast_to=BetaUserProfile,
        )

    async def retrieve(
        self,
        user_profile_id: str,
        *,
        betas: List[AnthropicBetaParam] | Omit = omit,
        workspace_id: str | Omit = omit,
        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
        # The extra values given here take precedence over values defined on the client or passed to this method.
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: float | httpx2.Timeout | None | NotGiven = not_given,
    ) -> BetaUserProfile:
        """
        Get User Profile

        Args:
          user_profile_id: The ID of the user profile to get (`uprof_...`).

          betas: Optional header to specify the beta version(s) you want to use.

          workspace_id: Optional header to select the Workspace for this request. The value is a
              Workspace ID (for example, `wrkspc_011CZkZaBF1tNoB5wlCeusgy`).

              Only needed for credentials that can act on more than one Workspace. A
              credential that belongs to a specific Workspace may omit it; if sent, it must
              match that Workspace.

          extra_headers: Send extra headers

          extra_query: Add additional query parameters to the request

          extra_body: Add additional JSON properties to the request

          timeout: Override the client-level default timeout for this request, in seconds
        """
        if not user_profile_id:
            raise ValueError(f"Expected a non-empty value for `user_profile_id` but received {user_profile_id!r}")
        extra_headers = {
            **strip_not_given(
                {
                    "anthropic-beta": ",".join(chain((str(e) for e in betas), ["user-profiles-2026-08-18"]))
                    if is_given(betas)
                    else not_given,
                    "anthropic-workspace-id": workspace_id,
                }
            ),
            **(extra_headers or {}),
        }
        extra_headers = {"anthropic-beta": "user-profiles-2026-08-18", **(extra_headers or {})}
        return await self._get(
            path_template("/v1/user_profiles/{user_profile_id}?beta=true", user_profile_id=user_profile_id),
            options=make_request_options(
                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
            ),
            cast_to=BetaUserProfile,
        )

    async def update(
        self,
        user_profile_id: str,
        *,
        access_type: Optional[Literal["application", "passthrough"]] | Omit = omit,
        external_id: Optional[str] | Omit = omit,
        external_user_details: BetaUserProfileExternalUserDetailsParams | Omit = omit,
        external_user_onboarded_at: Union[str, datetime] | Omit = omit,
        metadata: Dict[str, str] | Omit = omit,
        name: Optional[str] | Omit = omit,
        betas: List[AnthropicBetaParam] | Omit = omit,
        workspace_id: str | Omit = omit,
        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
        # The extra values given here take precedence over values defined on the client or passed to this method.
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: float | httpx2.Timeout | None | NotGiven = not_given,
    ) -> BetaUserProfile:
        """
        Update User Profile

        Args:
          user_profile_id: The ID of the user profile to update (`uprof_...`).

          access_type: How the platform uses the API on behalf of the entity this profile represents.
              `application`: the platform sells a product that uses the API behind the scenes,
              and the profile represents an individual end-user of that product.
              `passthrough`: the platform resells raw inference, and the profile identifies
              the resold-to company.

              - `application` - The user profile represents an individual end-user of a
                product that the platform builds on the API. New profiles get this value by
                default.
              - `passthrough` - The user profile represents a company that the platform
                resells Claude access to.

          external_id: If present, replaces the stored external_id. Omit to leave unchanged. Maximum
              255 characters. Accepted under the `user-profiles-2026-03-24` and
              `user-profiles-2026-08-18` beta headers; under `user-profiles-2026-09-04` send
              `external_user_details.reference_id` instead.

          external_user_details: Details about the entity this profile represents, as the platform states them.
              Each field sent replaces the stored value; omit a field to leave it unchanged.
              Once set, a value cannot be cleared and `null` is rejected. Accepted under the
              `user-profiles-2026-09-04` beta header only.

          external_user_onboarded_at: A timestamp in RFC 3339 format

          metadata: Key-value pairs to merge into the stored metadata. Keys provided overwrite
              existing values. To remove a key, set its value to an empty string. Keys not
              provided are left unchanged. Maximum 16 keys, with keys up to 64 characters and
              values up to 512 characters.

          name: If present, replaces the stored name. Omit to leave unchanged. Maximum 255
              characters.

          betas: Optional header to specify the beta version(s) you want to use.

          workspace_id: Optional header to select the Workspace for this request. The value is a
              Workspace ID (for example, `wrkspc_011CZkZaBF1tNoB5wlCeusgy`).

              Only needed for credentials that can act on more than one Workspace. A
              credential that belongs to a specific Workspace may omit it; if sent, it must
              match that Workspace.

          extra_headers: Send extra headers

          extra_query: Add additional query parameters to the request

          extra_body: Add additional JSON properties to the request

          timeout: Override the client-level default timeout for this request, in seconds
        """
        if not user_profile_id:
            raise ValueError(f"Expected a non-empty value for `user_profile_id` but received {user_profile_id!r}")
        extra_headers = {
            **strip_not_given(
                {
                    "anthropic-beta": ",".join(chain((str(e) for e in betas), ["user-profiles-2026-08-18"]))
                    if is_given(betas)
                    else not_given,
                    "anthropic-workspace-id": workspace_id,
                }
            ),
            **(extra_headers or {}),
        }
        extra_headers = {"anthropic-beta": "user-profiles-2026-08-18", **(extra_headers or {})}
        return await self._post(
            path_template("/v1/user_profiles/{user_profile_id}?beta=true", user_profile_id=user_profile_id),
            body={
                "access_type": access_type,
                "external_id": external_id,
                "external_user_details": external_user_details,
                "external_user_onboarded_at": external_user_onboarded_at,
                "metadata": metadata,
                "name": name,
            },
            options=make_request_options(
                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
            ),
            cast_to=BetaUserProfile,
        )

    def list(
        self,
        *,
        limit: int | Omit = omit,
        order: Literal["asc", "desc"] | Omit = omit,
        order_by: Literal["created_at", "name"] | Omit = omit,
        page: str | Omit = omit,
        betas: List[AnthropicBetaParam] | Omit = omit,
        workspace_id: str | Omit = omit,
        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
        # The extra values given here take precedence over values defined on the client or passed to this method.
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: float | httpx2.Timeout | None | NotGiven = not_given,
    ) -> AsyncPaginator[BetaUserProfile, AsyncPageCursor[BetaUserProfile]]:
        """
        List User Profiles

        Args:
          limit: The maximum number of user profiles to return, from 1 to 100. Defaults to 20.

          order: The sort direction, applied to the field that `order_by` selects. Defaults to
              `desc`.

              - `asc` - Oldest first when `order_by` is `created_at`, or names in ascending
                order when `order_by` is `name`.
              - `desc` - Newest first when `order_by` is `created_at`, or names in descending
                order when `order_by` is `name`. This is the default.

          order_by: The field to sort user profiles by, in the direction that `order` sets. Defaults
              to `created_at`.

              - `created_at` - Sort by when each user profile was created. This is the
                default.
              - `name` - Sort by `name`, ignoring the case of ASCII letters. Profiles without
                a name come last in either direction.

          page: The cursor for the page to return, taken from `next_page` in a previous
              response.

              Leave it out to get the first page.

          betas: Optional header to specify the beta version(s) you want to use.

          workspace_id: Optional header to select the Workspace for this request. The value is a
              Workspace ID (for example, `wrkspc_011CZkZaBF1tNoB5wlCeusgy`).

              Only needed for credentials that can act on more than one Workspace. A
              credential that belongs to a specific Workspace may omit it; if sent, it must
              match that Workspace.

          extra_headers: Send extra headers

          extra_query: Add additional query parameters to the request

          extra_body: Add additional JSON properties to the request

          timeout: Override the client-level default timeout for this request, in seconds
        """
        extra_headers = {
            **strip_not_given(
                {
                    "anthropic-beta": ",".join(chain((str(e) for e in betas), ["user-profiles-2026-08-18"]))
                    if is_given(betas)
                    else not_given,
                    "anthropic-workspace-id": workspace_id,
                }
            ),
            **(extra_headers or {}),
        }
        extra_headers = {"anthropic-beta": "user-profiles-2026-08-18", **(extra_headers or {})}
        return self._get_api_list(
            "/v1/user_profiles?beta=true",
            page=AsyncPageCursor[BetaUserProfile],
            options=make_request_options(
                extra_headers=extra_headers,
                extra_query=extra_query,
                extra_body=extra_body,
                timeout=timeout,
                query={
                    "limit": limit,
                    "order": order,
                    "order_by": order_by,
                    "page": page,
                },
            ),
            model=BetaUserProfile,
        )

    async def create_enrollment_url(
        self,
        user_profile_id: str,
        *,
        betas: List[AnthropicBetaParam] | Omit = omit,
        workspace_id: str | Omit = omit,
        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
        # The extra values given here take precedence over values defined on the client or passed to this method.
        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: float | httpx2.Timeout | None | NotGiven = not_given,
    ) -> BetaUserProfileEnrollmentURL:
        """
        Create Enrollment URL

        Args:
          user_profile_id: The ID of the user profile to create an enrollment URL for (`uprof_...`).

          betas: Optional header to specify the beta version(s) you want to use.

          workspace_id: Optional header to select the Workspace for this request. The value is a
              Workspace ID (for example, `wrkspc_011CZkZaBF1tNoB5wlCeusgy`).

              Only needed for credentials that can act on more than one Workspace. A
              credential that belongs to a specific Workspace may omit it; if sent, it must
              match that Workspace.

          extra_headers: Send extra headers

          extra_query: Add additional query parameters to the request

          extra_body: Add additional JSON properties to the request

          timeout: Override the client-level default timeout for this request, in seconds
        """
        if not user_profile_id:
            raise ValueError(f"Expected a non-empty value for `user_profile_id` but received {user_profile_id!r}")
        extra_headers = {
            **strip_not_given(
                {
                    "anthropic-beta": ",".join(chain((str(e) for e in betas), ["user-profiles-2026-08-18"]))
                    if is_given(betas)
                    else not_given,
                    "anthropic-workspace-id": workspace_id,
                }
            ),
            **(extra_headers or {}),
        }
        extra_headers = {"anthropic-beta": "user-profiles-2026-08-18", **(extra_headers or {})}
        return await self._post(
            path_template(
                "/v1/user_profiles/{user_profile_id}/enrollment_url?beta=true", user_profile_id=user_profile_id
            ),
            options=make_request_options(
                extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
            ),
            cast_to=BetaUserProfileEnrollmentURL,
        )


class UserProfilesWithRawResponse:
    def __init__(self, user_profiles: UserProfiles) -> None:
        self._user_profiles = user_profiles

        self.create = to_raw_response_wrapper(
            user_profiles.create,
        )
        self.retrieve = to_raw_response_wrapper(
            user_profiles.retrieve,
        )
        self.update = to_raw_response_wrapper(
            user_profiles.update,
        )
        self.list = to_raw_response_wrapper(
            user_profiles.list,
        )
        self.create_enrollment_url = to_raw_response_wrapper(
            user_profiles.create_enrollment_url,
        )


class AsyncUserProfilesWithRawResponse:
    def __init__(self, user_profiles: AsyncUserProfiles) -> None:
        self._user_profiles = user_profiles

        self.create = async_to_raw_response_wrapper(
            user_profiles.create,
        )
        self.retrieve = async_to_raw_response_wrapper(
            user_profiles.retrieve,
        )
        self.update = async_to_raw_response_wrapper(
            user_profiles.update,
        )
        self.list = async_to_raw_response_wrapper(
            user_profiles.list,
        )
        self.create_enrollment_url = async_to_raw_response_wrapper(
            user_profiles.create_enrollment_url,
        )


class UserProfilesWithStreamingResponse:
    def __init__(self, user_profiles: UserProfiles) -> None:
        self._user_profiles = user_profiles

        self.create = to_streamed_response_wrapper(
            user_profiles.create,
        )
        self.retrieve = to_streamed_response_wrapper(
            user_profiles.retrieve,
        )
        self.update = to_streamed_response_wrapper(
            user_profiles.update,
        )
        self.list = to_streamed_response_wrapper(
            user_profiles.list,
        )
        self.create_enrollment_url = to_streamed_response_wrapper(
            user_profiles.create_enrollment_url,
        )


class AsyncUserProfilesWithStreamingResponse:
    def __init__(self, user_profiles: AsyncUserProfiles) -> None:
        self._user_profiles = user_profiles

        self.create = async_to_streamed_response_wrapper(
            user_profiles.create,
        )
        self.retrieve = async_to_streamed_response_wrapper(
            user_profiles.retrieve,
        )
        self.update = async_to_streamed_response_wrapper(
            user_profiles.update,
        )
        self.list = async_to_streamed_response_wrapper(
            user_profiles.list,
        )
        self.create_enrollment_url = async_to_streamed_response_wrapper(
            user_profiles.create_enrollment_url,
        )
