# This file was auto-generated by Fern from our API Definition.

import typing
from json.decoder import JSONDecodeError

from ...core.api_error import ApiError
from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ...core.http_response import AsyncHttpResponse, HttpResponse
from ...core.jsonable_encoder import jsonable_encoder
from ...core.pydantic_utilities import parse_obj_as
from ...core.request_options import RequestOptions
from ...core.serialization import convert_and_respect_annotation_metadata
from ...errors.bad_request_error import BadRequestError
from ...errors.internal_server_error import InternalServerError
from ...errors.not_found_error import NotFoundError
from ...errors.unauthorized_error import UnauthorizedError
from ...types.autofill_dlc_campaign_response import AutofillDlcCampaignResponse
from ...types.campaign_submission_result import CampaignSubmissionResult
from ...types.campaign_validation_result import CampaignValidationResult
from ...types.dlc_campaign_with_extended_brand_and_status import DlcCampaignWithExtendedBrandAndStatus
from ...types.error import Error
from .types.dlc_campaign_keywords import DlcCampaignKeywords
from .types.dlc_campaign_links import DlcCampaignLinks
from .types.dlc_campaign_options import DlcCampaignOptions
from .types.dlc_campaign_use_case import DlcCampaignUseCase

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class RawDlcClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def autofill(
        self,
        *,
        additional_info: typing.Optional[str] = OMIT,
        campaign_id: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[AutofillDlcCampaignResponse]:
        """
        Generate campaign details based off existing campaign and the brand it's connected to.

        Parameters
        ----------
        additional_info : typing.Optional[str]
            Any additional information you want to provide.

        campaign_id : typing.Optional[str]
            Unique identifier for the campaign.
            - When autofilling 10DLC campaigns, it must begin with the prefix `dlc_` (e.g., `dlc_1234567890`)
            - When autofilling Toll-Free campaigns, it must begin with the prefix `tf_` (e.g., `tf_1234567890`)
            - When autofilling RCS campaigns, it must begin with the prefix `rcs_` (e.g., `rcs_1234567890`)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[AutofillDlcCampaignResponse]
            Returns autofilled 10DLC information.
        """
        _response = self._client_wrapper.httpx_client.request(
            "campaigns/dlc/autofill",
            method="POST",
            json={
                "additionalInfo": additional_info,
                "campaignId": campaign_id,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AutofillDlcCampaignResponse,
                    parse_obj_as(
                        type_=AutofillDlcCampaignResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get(
        self, campaign_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[DlcCampaignWithExtendedBrandAndStatus]:
        """
        Retrieve 10DLC campaign.

        Parameters
        ----------
        campaign_id : str
            Unique identifier of the 10DLC campaign. This identifier is a string that always begins with the prefix `dlc_`, for example: `dlc_1234567890`.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[DlcCampaignWithExtendedBrandAndStatus]
            Successfully retrieved.
        """
        _response = self._client_wrapper.httpx_client.request(
            f"campaigns/dlc/{jsonable_encoder(campaign_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DlcCampaignWithExtendedBrandAndStatus,
                    parse_obj_as(
                        type_=DlcCampaignWithExtendedBrandAndStatus,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def submit(
        self, campaign_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[CampaignSubmissionResult]:
        """
        Submit your 10DLC campaign for approval and activation with carriers.

        Parameters
        ----------
        campaign_id : str
            Unique identifier of the 10DLC campaign to submit.
            <br><br> This identifier is a string that always begins with the prefix `dlc_`, for example: `dlc_1234567890`.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[CampaignSubmissionResult]
            Successfully submitted 10DLC campaign for approval.
        """
        _response = self._client_wrapper.httpx_client.request(
            f"campaigns/dlc/submit/{jsonable_encoder(campaign_id)}",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CampaignSubmissionResult,
                    parse_obj_as(
                        type_=CampaignSubmissionResult,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def upsert(
        self,
        *,
        auto_renew: typing.Optional[bool] = OMIT,
        brand: typing.Optional[str] = OMIT,
        campaign_id: typing.Optional[str] = OMIT,
        description: typing.Optional[str] = OMIT,
        keywords: typing.Optional[DlcCampaignKeywords] = OMIT,
        links: typing.Optional[DlcCampaignLinks] = OMIT,
        message_flow: typing.Optional[str] = OMIT,
        name: typing.Optional[str] = OMIT,
        options: typing.Optional[DlcCampaignOptions] = OMIT,
        sample_messages: typing.Optional[typing.Sequence[str]] = OMIT,
        use_case: typing.Optional[DlcCampaignUseCase] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[DlcCampaignWithExtendedBrandAndStatus]:
        """
        Create a new 10DLC campaign or update an existing one.

        <Note>
        **To create a new campaign:** Omit `campaignId` — one will be generated automatically.

        **Before you start:** Create a [brand](/api-reference/brands/upsert) first — you'll need its `id` for the [`brand`](#request.body.brand) field.

        All fields are **required** unless specified otherwise, and will be validated when [submitted](/api-reference/campaigns/10-dlc/submit).

        **See the response for example values for each field.**
        </Note>

        Parameters
        ----------
        auto_renew : typing.Optional[bool]
            Whether the campaign renews automatically.

        brand : typing.Optional[str]
            Brand id. This identifier is a string that always begins with the prefix `b_`, for example: `b_1234567890`.

        campaign_id : typing.Optional[str]
            Unique identifier for the campaign. This identifier is a string that always begins with the prefix `dlc_`, for example: `dlc_1234567890`.

        description : typing.Optional[str]
            Description of the campaign. Explain the purpose, use case, and types of messages your campaign will send.

            **Example:** `This campaign allows users who have specifically opted in to interact with our chatbot for a range of automated services, including order status notifications, shipping updates, security alerts, and help desk support. Users can manage their account, receive transactional SMS prompts, and access interactive support. They may also share images, such as receipts, and receive immediate responses for support or account updates. All messages are strictly transactional or support-related, never unsolicited, and initiated only after clear user consent.`

        keywords : typing.Optional[DlcCampaignKeywords]
            Keyword response configuration.

        links : typing.Optional[DlcCampaignLinks]
            Legal documentation links.

        message_flow : typing.Optional[str]
            Describe your opt-in workflow. See the [Opt-In Methods and Workflow](/guides/campaigns/opt-in-compliance#opt-in-methods-and-workflow) section for requirements and examples.

        name : typing.Optional[str]
            Display name of the campaign.

        options : typing.Optional[DlcCampaignOptions]
            Campaign configuration options.

        sample_messages : typing.Optional[typing.Sequence[str]]
            Example messages for the campaign. Include 1-5 messages that represent the types of messages you will send. See the [Sample Messages](/guides/campaigns/opt-in-compliance#sample-messages) section for requirements and examples.

        use_case : typing.Optional[DlcCampaignUseCase]
            Use case for the campaign.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[DlcCampaignWithExtendedBrandAndStatus]
            Successfully created or updated DLC campaign.
        """
        _response = self._client_wrapper.httpx_client.request(
            "campaigns/dlc",
            method="POST",
            json={
                "autoRenew": auto_renew,
                "brand": brand,
                "campaignId": campaign_id,
                "description": description,
                "keywords": convert_and_respect_annotation_metadata(
                    object_=keywords, annotation=DlcCampaignKeywords, direction="write"
                ),
                "links": convert_and_respect_annotation_metadata(
                    object_=links, annotation=DlcCampaignLinks, direction="write"
                ),
                "messageFlow": message_flow,
                "name": name,
                "options": convert_and_respect_annotation_metadata(
                    object_=options, annotation=DlcCampaignOptions, direction="write"
                ),
                "sampleMessages": sample_messages,
                "useCase": convert_and_respect_annotation_metadata(
                    object_=use_case, annotation=DlcCampaignUseCase, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DlcCampaignWithExtendedBrandAndStatus,
                    parse_obj_as(
                        type_=DlcCampaignWithExtendedBrandAndStatus,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def validate(
        self,
        *,
        campaign_id: str,
        additional_info: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[CampaignValidationResult]:
        """
        Validate your 10DLC campaign configuration against carrier requirements and compliance rules.

        Parameters
        ----------
        campaign_id : str
            Unique identifier for the campaign.
            - When validating 10DLC campaigns, it must begin with the prefix `dlc_` (e.g., `dlc_1234567890`)
            - When validating toll-free campaigns, it must begin with the prefix `tf_` (e.g., `tf_1234567890`)
            - When validating RCS campaigns, it must begin with the prefix `rcs_` (e.g., `rcs_1234567890`)

        additional_info : typing.Optional[str]
            Any additional information you want to provide.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[CampaignValidationResult]
            Returns validation results.
        """
        _response = self._client_wrapper.httpx_client.request(
            "campaigns/dlc/validate",
            method="POST",
            json={
                "additionalInfo": additional_info,
                "campaignId": campaign_id,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CampaignValidationResult,
                    parse_obj_as(
                        type_=CampaignValidationResult,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)


class AsyncRawDlcClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def autofill(
        self,
        *,
        additional_info: typing.Optional[str] = OMIT,
        campaign_id: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[AutofillDlcCampaignResponse]:
        """
        Generate campaign details based off existing campaign and the brand it's connected to.

        Parameters
        ----------
        additional_info : typing.Optional[str]
            Any additional information you want to provide.

        campaign_id : typing.Optional[str]
            Unique identifier for the campaign.
            - When autofilling 10DLC campaigns, it must begin with the prefix `dlc_` (e.g., `dlc_1234567890`)
            - When autofilling Toll-Free campaigns, it must begin with the prefix `tf_` (e.g., `tf_1234567890`)
            - When autofilling RCS campaigns, it must begin with the prefix `rcs_` (e.g., `rcs_1234567890`)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[AutofillDlcCampaignResponse]
            Returns autofilled 10DLC information.
        """
        _response = await self._client_wrapper.httpx_client.request(
            "campaigns/dlc/autofill",
            method="POST",
            json={
                "additionalInfo": additional_info,
                "campaignId": campaign_id,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AutofillDlcCampaignResponse,
                    parse_obj_as(
                        type_=AutofillDlcCampaignResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get(
        self, campaign_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[DlcCampaignWithExtendedBrandAndStatus]:
        """
        Retrieve 10DLC campaign.

        Parameters
        ----------
        campaign_id : str
            Unique identifier of the 10DLC campaign. This identifier is a string that always begins with the prefix `dlc_`, for example: `dlc_1234567890`.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[DlcCampaignWithExtendedBrandAndStatus]
            Successfully retrieved.
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"campaigns/dlc/{jsonable_encoder(campaign_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DlcCampaignWithExtendedBrandAndStatus,
                    parse_obj_as(
                        type_=DlcCampaignWithExtendedBrandAndStatus,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def submit(
        self, campaign_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[CampaignSubmissionResult]:
        """
        Submit your 10DLC campaign for approval and activation with carriers.

        Parameters
        ----------
        campaign_id : str
            Unique identifier of the 10DLC campaign to submit.
            <br><br> This identifier is a string that always begins with the prefix `dlc_`, for example: `dlc_1234567890`.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[CampaignSubmissionResult]
            Successfully submitted 10DLC campaign for approval.
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"campaigns/dlc/submit/{jsonable_encoder(campaign_id)}",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CampaignSubmissionResult,
                    parse_obj_as(
                        type_=CampaignSubmissionResult,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def upsert(
        self,
        *,
        auto_renew: typing.Optional[bool] = OMIT,
        brand: typing.Optional[str] = OMIT,
        campaign_id: typing.Optional[str] = OMIT,
        description: typing.Optional[str] = OMIT,
        keywords: typing.Optional[DlcCampaignKeywords] = OMIT,
        links: typing.Optional[DlcCampaignLinks] = OMIT,
        message_flow: typing.Optional[str] = OMIT,
        name: typing.Optional[str] = OMIT,
        options: typing.Optional[DlcCampaignOptions] = OMIT,
        sample_messages: typing.Optional[typing.Sequence[str]] = OMIT,
        use_case: typing.Optional[DlcCampaignUseCase] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[DlcCampaignWithExtendedBrandAndStatus]:
        """
        Create a new 10DLC campaign or update an existing one.

        <Note>
        **To create a new campaign:** Omit `campaignId` — one will be generated automatically.

        **Before you start:** Create a [brand](/api-reference/brands/upsert) first — you'll need its `id` for the [`brand`](#request.body.brand) field.

        All fields are **required** unless specified otherwise, and will be validated when [submitted](/api-reference/campaigns/10-dlc/submit).

        **See the response for example values for each field.**
        </Note>

        Parameters
        ----------
        auto_renew : typing.Optional[bool]
            Whether the campaign renews automatically.

        brand : typing.Optional[str]
            Brand id. This identifier is a string that always begins with the prefix `b_`, for example: `b_1234567890`.

        campaign_id : typing.Optional[str]
            Unique identifier for the campaign. This identifier is a string that always begins with the prefix `dlc_`, for example: `dlc_1234567890`.

        description : typing.Optional[str]
            Description of the campaign. Explain the purpose, use case, and types of messages your campaign will send.

            **Example:** `This campaign allows users who have specifically opted in to interact with our chatbot for a range of automated services, including order status notifications, shipping updates, security alerts, and help desk support. Users can manage their account, receive transactional SMS prompts, and access interactive support. They may also share images, such as receipts, and receive immediate responses for support or account updates. All messages are strictly transactional or support-related, never unsolicited, and initiated only after clear user consent.`

        keywords : typing.Optional[DlcCampaignKeywords]
            Keyword response configuration.

        links : typing.Optional[DlcCampaignLinks]
            Legal documentation links.

        message_flow : typing.Optional[str]
            Describe your opt-in workflow. See the [Opt-In Methods and Workflow](/guides/campaigns/opt-in-compliance#opt-in-methods-and-workflow) section for requirements and examples.

        name : typing.Optional[str]
            Display name of the campaign.

        options : typing.Optional[DlcCampaignOptions]
            Campaign configuration options.

        sample_messages : typing.Optional[typing.Sequence[str]]
            Example messages for the campaign. Include 1-5 messages that represent the types of messages you will send. See the [Sample Messages](/guides/campaigns/opt-in-compliance#sample-messages) section for requirements and examples.

        use_case : typing.Optional[DlcCampaignUseCase]
            Use case for the campaign.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[DlcCampaignWithExtendedBrandAndStatus]
            Successfully created or updated DLC campaign.
        """
        _response = await self._client_wrapper.httpx_client.request(
            "campaigns/dlc",
            method="POST",
            json={
                "autoRenew": auto_renew,
                "brand": brand,
                "campaignId": campaign_id,
                "description": description,
                "keywords": convert_and_respect_annotation_metadata(
                    object_=keywords, annotation=DlcCampaignKeywords, direction="write"
                ),
                "links": convert_and_respect_annotation_metadata(
                    object_=links, annotation=DlcCampaignLinks, direction="write"
                ),
                "messageFlow": message_flow,
                "name": name,
                "options": convert_and_respect_annotation_metadata(
                    object_=options, annotation=DlcCampaignOptions, direction="write"
                ),
                "sampleMessages": sample_messages,
                "useCase": convert_and_respect_annotation_metadata(
                    object_=use_case, annotation=DlcCampaignUseCase, direction="write"
                ),
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DlcCampaignWithExtendedBrandAndStatus,
                    parse_obj_as(
                        type_=DlcCampaignWithExtendedBrandAndStatus,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def validate(
        self,
        *,
        campaign_id: str,
        additional_info: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[CampaignValidationResult]:
        """
        Validate your 10DLC campaign configuration against carrier requirements and compliance rules.

        Parameters
        ----------
        campaign_id : str
            Unique identifier for the campaign.
            - When validating 10DLC campaigns, it must begin with the prefix `dlc_` (e.g., `dlc_1234567890`)
            - When validating toll-free campaigns, it must begin with the prefix `tf_` (e.g., `tf_1234567890`)
            - When validating RCS campaigns, it must begin with the prefix `rcs_` (e.g., `rcs_1234567890`)

        additional_info : typing.Optional[str]
            Any additional information you want to provide.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[CampaignValidationResult]
            Returns validation results.
        """
        _response = await self._client_wrapper.httpx_client.request(
            "campaigns/dlc/validate",
            method="POST",
            json={
                "additionalInfo": additional_info,
                "campaignId": campaign_id,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CampaignValidationResult,
                    parse_obj_as(
                        type_=CampaignValidationResult,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        Error,
                        parse_obj_as(
                            type_=Error,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
