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

import type { BaseClientOptions, BaseRequestOptions } from "../../../../../../BaseClient.js";
import { type NormalizedClientOptionsWithAuth, normalizeClientOptionsWithAuth } from "../../../../../../BaseClient.js";
import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../core/headers.js";
import * as core from "../../../../../../core/index.js";
import * as environments from "../../../../../../environments.js";
import { handleNonStatusCodeError } from "../../../../../../errors/handleNonStatusCodeError.js";
import * as errors from "../../../../../../errors/index.js";
import * as Intercom from "../../../../../index.js";

export declare namespace ContactsClient {
    export interface Options extends BaseClientOptions {}

    export interface RequestOptions extends BaseRequestOptions {}
}

/**
 * Everything about your contacts
 */
export class ContactsClient {
    protected readonly _options: NormalizedClientOptionsWithAuth<ContactsClient.Options>;

    constructor(options: ContactsClient.Options = {}) {
        this._options = normalizeClientOptionsWithAuth(options);
    }

    /**
     * You can fetch a list of companies that are associated to a contact.
     *
     * @param {Intercom.unstable.ListCompaniesForAContactRequest} request
     * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration.
     *
     * @throws {@link Intercom.unstable.UnauthorizedError}
     * @throws {@link Intercom.unstable.NotFoundError}
     *
     * @example
     *     await client.unstable.contacts.listCompaniesForAContact({
     *         id: "63a07ddf05a32042dffac965"
     *     })
     */
    public listCompaniesForAContact(
        request: Intercom.unstable.ListCompaniesForAContactRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): core.HttpResponsePromise<Intercom.unstable.ContactAttachedCompanies> {
        return core.HttpResponsePromise.fromPromise(this.__listCompaniesForAContact(request, requestOptions));
    }

    private async __listCompaniesForAContact(
        request: Intercom.unstable.ListCompaniesForAContactRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): Promise<core.WithRawResponse<Intercom.unstable.ContactAttachedCompanies>> {
        const { id } = request;
        const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest();
        const _headers: core.Fetcher.Args["headers"] = mergeHeaders(
            _authRequest.headers,
            this._options?.headers,
            mergeOnlyDefinedHeaders({ "Intercom-Version": requestOptions?.version }),
            requestOptions?.headers,
        );
        const _response = await (this._options.fetcher ?? core.fetcher)({
            url: core.url.join(
                (await core.Supplier.get(this._options.baseUrl)) ??
                    (await core.Supplier.get(this._options.environment)) ??
                    environments.IntercomEnvironment.UsProduction,
                `contacts/${core.url.encodePathParam(id)}/companies`,
            ),
            method: "GET",
            headers: _headers,
            queryParameters: requestOptions?.queryParams,
            timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 20) * 1000,
            maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
            abortSignal: requestOptions?.abortSignal,
            fetchFn: this._options?.fetch,
            logging: this._options.logging,
        });
        if (_response.ok) {
            return {
                data: _response.body as Intercom.unstable.ContactAttachedCompanies,
                rawResponse: _response.rawResponse,
            };
        }

        if (_response.error.reason === "status-code") {
            switch (_response.error.statusCode) {
                case 401:
                    throw new Intercom.unstable.UnauthorizedError(
                        _response.error.body as Intercom.unstable.Error_,
                        _response.rawResponse,
                    );
                case 404:
                    throw new Intercom.unstable.NotFoundError(_response.error.body as unknown, _response.rawResponse);
                default:
                    throw new errors.IntercomError({
                        statusCode: _response.error.statusCode,
                        body: _response.error.body,
                        rawResponse: _response.rawResponse,
                    });
            }
        }

        return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/contacts/{id}/companies");
    }

    /**
     * You can fetch a list of segments that are associated to a contact.
     *
     * @param {Intercom.unstable.ListSegmentsForAContactRequest} request
     * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration.
     *
     * @throws {@link Intercom.unstable.UnauthorizedError}
     * @throws {@link Intercom.unstable.NotFoundError}
     *
     * @example
     *     await client.unstable.contacts.listSegmentsForAContact({
     *         contact_id: "63a07ddf05a32042dffac965"
     *     })
     */
    public listSegmentsForAContact(
        request: Intercom.unstable.ListSegmentsForAContactRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): core.HttpResponsePromise<Intercom.unstable.ContactSegments> {
        return core.HttpResponsePromise.fromPromise(this.__listSegmentsForAContact(request, requestOptions));
    }

    private async __listSegmentsForAContact(
        request: Intercom.unstable.ListSegmentsForAContactRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): Promise<core.WithRawResponse<Intercom.unstable.ContactSegments>> {
        const { contact_id: contactId } = request;
        const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest();
        const _headers: core.Fetcher.Args["headers"] = mergeHeaders(
            _authRequest.headers,
            this._options?.headers,
            mergeOnlyDefinedHeaders({ "Intercom-Version": requestOptions?.version }),
            requestOptions?.headers,
        );
        const _response = await (this._options.fetcher ?? core.fetcher)({
            url: core.url.join(
                (await core.Supplier.get(this._options.baseUrl)) ??
                    (await core.Supplier.get(this._options.environment)) ??
                    environments.IntercomEnvironment.UsProduction,
                `contacts/${core.url.encodePathParam(contactId)}/segments`,
            ),
            method: "GET",
            headers: _headers,
            queryParameters: requestOptions?.queryParams,
            timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 20) * 1000,
            maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
            abortSignal: requestOptions?.abortSignal,
            fetchFn: this._options?.fetch,
            logging: this._options.logging,
        });
        if (_response.ok) {
            return { data: _response.body as Intercom.unstable.ContactSegments, rawResponse: _response.rawResponse };
        }

        if (_response.error.reason === "status-code") {
            switch (_response.error.statusCode) {
                case 401:
                    throw new Intercom.unstable.UnauthorizedError(
                        _response.error.body as Intercom.unstable.Error_,
                        _response.rawResponse,
                    );
                case 404:
                    throw new Intercom.unstable.NotFoundError(_response.error.body as unknown, _response.rawResponse);
                default:
                    throw new errors.IntercomError({
                        statusCode: _response.error.statusCode,
                        body: _response.error.body,
                        rawResponse: _response.rawResponse,
                    });
            }
        }

        return handleNonStatusCodeError(
            _response.error,
            _response.rawResponse,
            "GET",
            "/contacts/{contact_id}/segments",
        );
    }

    /**
     * You can fetch a list of subscription types that are attached to a contact. These can be subscriptions that a user has 'opted-in' to or has 'opted-out' from, depending on the subscription type.
     * This will return a list of Subscription Type objects that the contact is associated with.
     *
     * The data property will show a combined list of:
     *
     *   1.Opt-out subscription types that the user has opted-out from.
     *   2.Opt-in subscription types that the user has opted-in to receiving.
     *
     * @param {Intercom.unstable.ListSubscriptionsForAContactRequest} request
     * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration.
     *
     * @throws {@link Intercom.unstable.UnauthorizedError}
     * @throws {@link Intercom.unstable.NotFoundError}
     *
     * @example
     *     await client.unstable.contacts.listSubscriptionsForAContact({
     *         contact_id: "63a07ddf05a32042dffac965"
     *     })
     */
    public listSubscriptionsForAContact(
        request: Intercom.unstable.ListSubscriptionsForAContactRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): core.HttpResponsePromise<Intercom.unstable.SubscriptionTypeList> {
        return core.HttpResponsePromise.fromPromise(this.__listSubscriptionsForAContact(request, requestOptions));
    }

    private async __listSubscriptionsForAContact(
        request: Intercom.unstable.ListSubscriptionsForAContactRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): Promise<core.WithRawResponse<Intercom.unstable.SubscriptionTypeList>> {
        const { contact_id: contactId } = request;
        const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest();
        const _headers: core.Fetcher.Args["headers"] = mergeHeaders(
            _authRequest.headers,
            this._options?.headers,
            mergeOnlyDefinedHeaders({ "Intercom-Version": requestOptions?.version }),
            requestOptions?.headers,
        );
        const _response = await (this._options.fetcher ?? core.fetcher)({
            url: core.url.join(
                (await core.Supplier.get(this._options.baseUrl)) ??
                    (await core.Supplier.get(this._options.environment)) ??
                    environments.IntercomEnvironment.UsProduction,
                `contacts/${core.url.encodePathParam(contactId)}/subscriptions`,
            ),
            method: "GET",
            headers: _headers,
            queryParameters: requestOptions?.queryParams,
            timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 20) * 1000,
            maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
            abortSignal: requestOptions?.abortSignal,
            fetchFn: this._options?.fetch,
            logging: this._options.logging,
        });
        if (_response.ok) {
            return {
                data: _response.body as Intercom.unstable.SubscriptionTypeList,
                rawResponse: _response.rawResponse,
            };
        }

        if (_response.error.reason === "status-code") {
            switch (_response.error.statusCode) {
                case 401:
                    throw new Intercom.unstable.UnauthorizedError(
                        _response.error.body as Intercom.unstable.Error_,
                        _response.rawResponse,
                    );
                case 404:
                    throw new Intercom.unstable.NotFoundError(_response.error.body as unknown, _response.rawResponse);
                default:
                    throw new errors.IntercomError({
                        statusCode: _response.error.statusCode,
                        body: _response.error.body,
                        rawResponse: _response.rawResponse,
                    });
            }
        }

        return handleNonStatusCodeError(
            _response.error,
            _response.rawResponse,
            "GET",
            "/contacts/{contact_id}/subscriptions",
        );
    }

    /**
     * You can fetch a list of all tags that are attached to a specific contact.
     *
     * @param {Intercom.unstable.ListTagsForAContactRequest} request
     * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration.
     *
     * @throws {@link Intercom.unstable.UnauthorizedError}
     * @throws {@link Intercom.unstable.NotFoundError}
     *
     * @example
     *     await client.unstable.contacts.listTagsForAContact({
     *         contact_id: "63a07ddf05a32042dffac965"
     *     })
     */
    public listTagsForAContact(
        request: Intercom.unstable.ListTagsForAContactRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): core.HttpResponsePromise<Intercom.unstable.TagList> {
        return core.HttpResponsePromise.fromPromise(this.__listTagsForAContact(request, requestOptions));
    }

    private async __listTagsForAContact(
        request: Intercom.unstable.ListTagsForAContactRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): Promise<core.WithRawResponse<Intercom.unstable.TagList>> {
        const { contact_id: contactId } = request;
        const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest();
        const _headers: core.Fetcher.Args["headers"] = mergeHeaders(
            _authRequest.headers,
            this._options?.headers,
            mergeOnlyDefinedHeaders({ "Intercom-Version": requestOptions?.version }),
            requestOptions?.headers,
        );
        const _response = await (this._options.fetcher ?? core.fetcher)({
            url: core.url.join(
                (await core.Supplier.get(this._options.baseUrl)) ??
                    (await core.Supplier.get(this._options.environment)) ??
                    environments.IntercomEnvironment.UsProduction,
                `contacts/${core.url.encodePathParam(contactId)}/tags`,
            ),
            method: "GET",
            headers: _headers,
            queryParameters: requestOptions?.queryParams,
            timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 20) * 1000,
            maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
            abortSignal: requestOptions?.abortSignal,
            fetchFn: this._options?.fetch,
            logging: this._options.logging,
        });
        if (_response.ok) {
            return { data: _response.body as Intercom.unstable.TagList, rawResponse: _response.rawResponse };
        }

        if (_response.error.reason === "status-code") {
            switch (_response.error.statusCode) {
                case 401:
                    throw new Intercom.unstable.UnauthorizedError(
                        _response.error.body as Intercom.unstable.Error_,
                        _response.rawResponse,
                    );
                case 404:
                    throw new Intercom.unstable.NotFoundError(_response.error.body as unknown, _response.rawResponse);
                default:
                    throw new errors.IntercomError({
                        statusCode: _response.error.statusCode,
                        body: _response.error.body,
                        rawResponse: _response.rawResponse,
                    });
            }
        }

        return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/contacts/{contact_id}/tags");
    }

    /**
     * You can fetch the details of a single contact.
     *
     * @param {Intercom.unstable.ShowContactRequest} request
     * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration.
     *
     * @throws {@link Intercom.unstable.UnauthorizedError}
     *
     * @example
     *     await client.unstable.contacts.showContact({
     *         id: "63a07ddf05a32042dffac965"
     *     })
     */
    public showContact(
        request: Intercom.unstable.ShowContactRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): core.HttpResponsePromise<Intercom.unstable.ShowContactResponse> {
        return core.HttpResponsePromise.fromPromise(this.__showContact(request, requestOptions));
    }

    private async __showContact(
        request: Intercom.unstable.ShowContactRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): Promise<core.WithRawResponse<Intercom.unstable.ShowContactResponse>> {
        const { id } = request;
        const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest();
        const _headers: core.Fetcher.Args["headers"] = mergeHeaders(
            _authRequest.headers,
            this._options?.headers,
            mergeOnlyDefinedHeaders({ "Intercom-Version": requestOptions?.version }),
            requestOptions?.headers,
        );
        const _response = await (this._options.fetcher ?? core.fetcher)({
            url: core.url.join(
                (await core.Supplier.get(this._options.baseUrl)) ??
                    (await core.Supplier.get(this._options.environment)) ??
                    environments.IntercomEnvironment.UsProduction,
                `contacts/${core.url.encodePathParam(id)}`,
            ),
            method: "GET",
            headers: _headers,
            queryParameters: requestOptions?.queryParams,
            timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 20) * 1000,
            maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
            abortSignal: requestOptions?.abortSignal,
            fetchFn: this._options?.fetch,
            logging: this._options.logging,
        });
        if (_response.ok) {
            return {
                data: _response.body as Intercom.unstable.ShowContactResponse,
                rawResponse: _response.rawResponse,
            };
        }

        if (_response.error.reason === "status-code") {
            switch (_response.error.statusCode) {
                case 401:
                    throw new Intercom.unstable.UnauthorizedError(
                        _response.error.body as Intercom.unstable.Error_,
                        _response.rawResponse,
                    );
                default:
                    throw new errors.IntercomError({
                        statusCode: _response.error.statusCode,
                        body: _response.error.body,
                        rawResponse: _response.rawResponse,
                    });
            }
        }

        return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/contacts/{id}");
    }

    /**
     * You can update an existing contact (ie. user or lead).
     *
     * {% admonition type="info" %}
     *   This endpoint handles both **contact updates** and **custom object associations**.
     *
     *   See _`update a contact with an association to a custom object instance`_ in the request/response examples to see the custom object association format.
     * {% /admonition %}
     *
     * @param {Intercom.unstable.UpdateContactRequest} request
     * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration.
     *
     * @throws {@link Intercom.unstable.UnauthorizedError}
     *
     * @example
     *     await client.unstable.contacts.updateContact({
     *         id: "63a07ddf05a32042dffac965",
     *         email: "joebloggs@intercom.io",
     *         name: "joe bloggs"
     *     })
     *
     * @example
     *     await client.unstable.contacts.updateContact({
     *         id: "63a07ddf05a32042dffac965",
     *         custom_attributes: {
     *             "order": [
     *                 "21"
     *             ]
     *         }
     *     })
     */
    public updateContact(
        request: Intercom.unstable.UpdateContactRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): core.HttpResponsePromise<Intercom.unstable.UpdateContactResponse> {
        return core.HttpResponsePromise.fromPromise(this.__updateContact(request, requestOptions));
    }

    private async __updateContact(
        request: Intercom.unstable.UpdateContactRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): Promise<core.WithRawResponse<Intercom.unstable.UpdateContactResponse>> {
        const { id, ..._body } = request;
        const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest();
        const _headers: core.Fetcher.Args["headers"] = mergeHeaders(
            _authRequest.headers,
            this._options?.headers,
            mergeOnlyDefinedHeaders({ "Intercom-Version": requestOptions?.version }),
            requestOptions?.headers,
        );
        const _response = await (this._options.fetcher ?? core.fetcher)({
            url: core.url.join(
                (await core.Supplier.get(this._options.baseUrl)) ??
                    (await core.Supplier.get(this._options.environment)) ??
                    environments.IntercomEnvironment.UsProduction,
                `contacts/${core.url.encodePathParam(id)}`,
            ),
            method: "PUT",
            headers: _headers,
            contentType: "application/json",
            queryParameters: requestOptions?.queryParams,
            requestType: "json",
            body: _body,
            timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 20) * 1000,
            maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
            abortSignal: requestOptions?.abortSignal,
            fetchFn: this._options?.fetch,
            logging: this._options.logging,
        });
        if (_response.ok) {
            return {
                data: _response.body as Intercom.unstable.UpdateContactResponse,
                rawResponse: _response.rawResponse,
            };
        }

        if (_response.error.reason === "status-code") {
            switch (_response.error.statusCode) {
                case 401:
                    throw new Intercom.unstable.UnauthorizedError(
                        _response.error.body as Intercom.unstable.Error_,
                        _response.rawResponse,
                    );
                default:
                    throw new errors.IntercomError({
                        statusCode: _response.error.statusCode,
                        body: _response.error.body,
                        rawResponse: _response.rawResponse,
                    });
            }
        }

        return handleNonStatusCodeError(_response.error, _response.rawResponse, "PUT", "/contacts/{id}");
    }

    /**
     * You can delete a single contact.
     *
     * @param {Intercom.unstable.DeleteContactRequest} request
     * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration.
     *
     * @throws {@link Intercom.unstable.UnauthorizedError}
     *
     * @example
     *     await client.unstable.contacts.deleteContact({
     *         id: "id"
     *     })
     */
    public deleteContact(
        request: Intercom.unstable.DeleteContactRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): core.HttpResponsePromise<Intercom.unstable.ContactDeleted> {
        return core.HttpResponsePromise.fromPromise(this.__deleteContact(request, requestOptions));
    }

    private async __deleteContact(
        request: Intercom.unstable.DeleteContactRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): Promise<core.WithRawResponse<Intercom.unstable.ContactDeleted>> {
        const { id } = request;
        const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest();
        const _headers: core.Fetcher.Args["headers"] = mergeHeaders(
            _authRequest.headers,
            this._options?.headers,
            mergeOnlyDefinedHeaders({ "Intercom-Version": requestOptions?.version }),
            requestOptions?.headers,
        );
        const _response = await (this._options.fetcher ?? core.fetcher)({
            url: core.url.join(
                (await core.Supplier.get(this._options.baseUrl)) ??
                    (await core.Supplier.get(this._options.environment)) ??
                    environments.IntercomEnvironment.UsProduction,
                `contacts/${core.url.encodePathParam(id)}`,
            ),
            method: "DELETE",
            headers: _headers,
            queryParameters: requestOptions?.queryParams,
            timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 20) * 1000,
            maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
            abortSignal: requestOptions?.abortSignal,
            fetchFn: this._options?.fetch,
            logging: this._options.logging,
        });
        if (_response.ok) {
            return { data: _response.body as Intercom.unstable.ContactDeleted, rawResponse: _response.rawResponse };
        }

        if (_response.error.reason === "status-code") {
            switch (_response.error.statusCode) {
                case 401:
                    throw new Intercom.unstable.UnauthorizedError(
                        _response.error.body as Intercom.unstable.Error_,
                        _response.rawResponse,
                    );
                default:
                    throw new errors.IntercomError({
                        statusCode: _response.error.statusCode,
                        body: _response.error.body,
                        rawResponse: _response.rawResponse,
                    });
            }
        }

        return handleNonStatusCodeError(_response.error, _response.rawResponse, "DELETE", "/contacts/{id}");
    }

    /**
     * You can merge a contact with a `role` of `lead` into a contact with a `role` of `user`.
     *
     * @param {Intercom.unstable.MergeContactsRequest} request
     * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration.
     *
     * @throws {@link Intercom.unstable.UnauthorizedError}
     *
     * @example
     *     await client.unstable.contacts.mergeContact({
     *         from: "6762f0d51bb69f9f2193bb7f",
     *         into: "6762f0d51bb69f9f2193bb80"
     *     })
     */
    public mergeContact(
        request: Intercom.unstable.MergeContactsRequest = {},
        requestOptions?: ContactsClient.RequestOptions,
    ): core.HttpResponsePromise<Intercom.unstable.MergeContactResponse> {
        return core.HttpResponsePromise.fromPromise(this.__mergeContact(request, requestOptions));
    }

    private async __mergeContact(
        request: Intercom.unstable.MergeContactsRequest = {},
        requestOptions?: ContactsClient.RequestOptions,
    ): Promise<core.WithRawResponse<Intercom.unstable.MergeContactResponse>> {
        const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest();
        const _headers: core.Fetcher.Args["headers"] = mergeHeaders(
            _authRequest.headers,
            this._options?.headers,
            mergeOnlyDefinedHeaders({ "Intercom-Version": requestOptions?.version }),
            requestOptions?.headers,
        );
        const _response = await (this._options.fetcher ?? core.fetcher)({
            url: core.url.join(
                (await core.Supplier.get(this._options.baseUrl)) ??
                    (await core.Supplier.get(this._options.environment)) ??
                    environments.IntercomEnvironment.UsProduction,
                "contacts/merge",
            ),
            method: "POST",
            headers: _headers,
            contentType: "application/json",
            queryParameters: requestOptions?.queryParams,
            requestType: "json",
            body: request,
            timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 20) * 1000,
            maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
            abortSignal: requestOptions?.abortSignal,
            fetchFn: this._options?.fetch,
            logging: this._options.logging,
        });
        if (_response.ok) {
            return {
                data: _response.body as Intercom.unstable.MergeContactResponse,
                rawResponse: _response.rawResponse,
            };
        }

        if (_response.error.reason === "status-code") {
            switch (_response.error.statusCode) {
                case 401:
                    throw new Intercom.unstable.UnauthorizedError(
                        _response.error.body as Intercom.unstable.Error_,
                        _response.rawResponse,
                    );
                default:
                    throw new errors.IntercomError({
                        statusCode: _response.error.statusCode,
                        body: _response.error.body,
                        rawResponse: _response.rawResponse,
                    });
            }
        }

        return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/contacts/merge");
    }

    /**
     * You can search for multiple contacts by the value of their attributes in order to fetch exactly who you want.
     *
     * To search for contacts, you need to send a `POST` request to `https://api.intercom.io/contacts/search`.
     *
     * This will accept a query object in the body which will define your filters in order to search for contacts.
     *
     * {% admonition type="warning" name="Optimizing search queries" %}
     *   Search queries can be complex, so optimizing them can help the performance of your search.
     *   Use the `AND` and `OR` operators to combine multiple filters to get the exact results you need and utilize
     *   pagination to limit the number of results returned. The default is `50` results per page.
     *   See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#example-search-conversations-request) for more details on how to use the `starting_after` param.
     * {% /admonition %}
     * ### Contact Creation Delay
     *
     * If a contact has recently been created, there is a possibility that it will not yet be available when searching. This means that it may not appear in the response. This delay can take a few minutes. If you need to be instantly notified it is recommended to use webhooks and iterate to see if they match your search filters.
     *
     * ### Nesting & Limitations
     *
     * You can nest these filters in order to get even more granular insights that pinpoint exactly what you need. Example: (1 OR 2) AND (3 OR 4).
     * There are some limitations to the amount of multiple's there can be:
     * * There's a limit of max 2 nested filters
     * * There's a limit of max 15 filters for each AND or OR group
     *
     * ### Searching for Timestamp Fields
     *
     * All timestamp fields (created_at, updated_at etc.) are indexed as Dates for Contact Search queries; Datetime queries are not currently supported. This means you can only query for timestamp fields by day - not hour, minute or second.
     * For example, if you search for all Contacts with a created_at value greater (>) than 1577869200 (the UNIX timestamp for January 1st, 2020 9:00 AM), that will be interpreted as 1577836800 (January 1st, 2020 12:00 AM). The search results will then include Contacts created from January 2nd, 2020 12:00 AM onwards.
     * If you'd like to get contacts created on January 1st, 2020 you should search with a created_at value equal (=) to 1577836800 (January 1st, 2020 12:00 AM).
     * This behaviour applies only to timestamps used in search queries. The search results will still contain the full UNIX timestamp and be sorted accordingly.
     *
     * ### Accepted Fields
     *
     * Most key listed as part of the Contacts Model are searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foorbar"`).
     *
     * | Field                              | Type                           |
     * | ---------------------------------- | ------------------------------ |
     * | id                                 | String                         |
     * | role                               | String<br>Accepts user or lead |
     * | name                               | String                         |
     * | avatar                             | String                         |
     * | owner_id                           | Integer                        |
     * | email                              | String                         |
     * | email_domain                       | String                         |
     * | phone                              | String                         |
     * | formatted_phone                    | String                         |
     * | external_id                        | String                         |
     * | created_at                         | Date (UNIX Timestamp)          |
     * | signed_up_at                       | Date (UNIX Timestamp)          |
     * | updated_at                         | Date (UNIX Timestamp)          |
     * | last_seen_at                       | Date (UNIX Timestamp)          |
     * | last_contacted_at                  | Date (UNIX Timestamp)          |
     * | last_replied_at                    | Date (UNIX Timestamp)          |
     * | last_email_opened_at               | Date (UNIX Timestamp)          |
     * | last_email_clicked_at              | Date (UNIX Timestamp)          |
     * | language_override                  | String                         |
     * | browser                            | String                         |
     * | browser_language                   | String                         |
     * | os                                 | String                         |
     * | location.country                   | String                         |
     * | location.region                    | String                         |
     * | location.city                      | String                         |
     * | unsubscribed_from_emails           | Boolean                        |
     * | marked_email_as_spam               | Boolean                        |
     * | has_hard_bounced                   | Boolean                        |
     * | ios_last_seen_at                   | Date (UNIX Timestamp)          |
     * | ios_app_version                    | String                         |
     * | ios_device                         | String                         |
     * | ios_app_device                     | String                         |
     * | ios_os_version                     | String                         |
     * | ios_app_name                       | String                         |
     * | ios_sdk_version                    | String                         |
     * | android_last_seen_at               | Date (UNIX Timestamp)          |
     * | android_app_version                | String                         |
     * | android_device                     | String                         |
     * | android_app_name                   | String                         |
     * | andoid_sdk_version                 | String                         |
     * | segment_id                         | String                         |
     * | tag_id                             | String                         |
     * | custom_attributes.{attribute_name} | String                         |
     *
     * ### Accepted Operators
     *
     * {% admonition type="warning" name="Searching based on `created_at`" %}
     *   You cannot use the `<=` or `>=` operators to search by `created_at`.
     * {% /admonition %}
     *
     * The table below shows the operators you can use to define how you want to search for the value.  The operator should be put in as a string (`"="`). The operator has to be compatible with the field's type (eg. you cannot search with `>` for a given string value as it's only compatible for integer's and dates).
     *
     * | Operator | Valid Types                      | Description                                                      |
     * | :------- | :------------------------------- | :--------------------------------------------------------------- |
     * | =        | All                              | Equals                                                           |
     * | !=       | All                              | Doesn't Equal                                                    |
     * | IN       | All                              | In<br>Shortcut for `OR` queries<br>Values must be in Array       |
     * | NIN      | All                              | Not In<br>Shortcut for `OR !` queries<br>Values must be in Array |
     * | >        | Integer<br>Date (UNIX Timestamp) | Greater than                                                     |
     * | <       | Integer<br>Date (UNIX Timestamp) | Lower than                                                       |
     * | ~        | String                           | Contains                                                         |
     * | !~       | String                           | Doesn't Contain                                                  |
     * | ^        | String                           | Starts With                                                      |
     * | $        | String                           | Ends With                                                        |
     *
     * @param {Intercom.unstable.SearchRequest} request
     * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration.
     *
     * @throws {@link Intercom.unstable.UnauthorizedError}
     *
     * @example
     *     await client.unstable.contacts.searchContacts({
     *         query: {
     *             operator: "AND",
     *             value: [{
     *                     field: "created_at",
     *                     operator: ">",
     *                     value: "1306054154"
     *                 }]
     *         },
     *         pagination: {
     *             per_page: 5
     *         }
     *     })
     */
    public searchContacts(
        request: Intercom.unstable.SearchRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): core.HttpResponsePromise<Intercom.unstable.ContactList> {
        return core.HttpResponsePromise.fromPromise(this.__searchContacts(request, requestOptions));
    }

    private async __searchContacts(
        request: Intercom.unstable.SearchRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): Promise<core.WithRawResponse<Intercom.unstable.ContactList>> {
        const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest();
        const _headers: core.Fetcher.Args["headers"] = mergeHeaders(
            _authRequest.headers,
            this._options?.headers,
            mergeOnlyDefinedHeaders({ "Intercom-Version": requestOptions?.version }),
            requestOptions?.headers,
        );
        const _response = await (this._options.fetcher ?? core.fetcher)({
            url: core.url.join(
                (await core.Supplier.get(this._options.baseUrl)) ??
                    (await core.Supplier.get(this._options.environment)) ??
                    environments.IntercomEnvironment.UsProduction,
                "contacts/search",
            ),
            method: "POST",
            headers: _headers,
            contentType: "application/json",
            queryParameters: requestOptions?.queryParams,
            requestType: "json",
            body: request,
            timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 20) * 1000,
            maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
            abortSignal: requestOptions?.abortSignal,
            fetchFn: this._options?.fetch,
            logging: this._options.logging,
        });
        if (_response.ok) {
            return { data: _response.body as Intercom.unstable.ContactList, rawResponse: _response.rawResponse };
        }

        if (_response.error.reason === "status-code") {
            switch (_response.error.statusCode) {
                case 401:
                    throw new Intercom.unstable.UnauthorizedError(
                        _response.error.body as Intercom.unstable.Error_,
                        _response.rawResponse,
                    );
                default:
                    throw new errors.IntercomError({
                        statusCode: _response.error.statusCode,
                        body: _response.error.body,
                        rawResponse: _response.rawResponse,
                    });
            }
        }

        return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/contacts/search");
    }

    /**
     * You can fetch a list of all contacts (ie. users or leads) in your workspace.
     * {% admonition type="warning" name="Pagination" %}
     *   You can use pagination to limit the number of results returned. The default is `50` results per page.
     *   See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#pagination-for-list-apis) for more details on how to use the `starting_after` param.
     * {% /admonition %}
     *
     * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration.
     *
     * @throws {@link Intercom.unstable.UnauthorizedError}
     *
     * @example
     *     await client.unstable.contacts.listContacts()
     */
    public listContacts(
        requestOptions?: ContactsClient.RequestOptions,
    ): core.HttpResponsePromise<Intercom.unstable.ContactList> {
        return core.HttpResponsePromise.fromPromise(this.__listContacts(requestOptions));
    }

    private async __listContacts(
        requestOptions?: ContactsClient.RequestOptions,
    ): Promise<core.WithRawResponse<Intercom.unstable.ContactList>> {
        const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest();
        const _headers: core.Fetcher.Args["headers"] = mergeHeaders(
            _authRequest.headers,
            this._options?.headers,
            mergeOnlyDefinedHeaders({ "Intercom-Version": requestOptions?.version }),
            requestOptions?.headers,
        );
        const _response = await (this._options.fetcher ?? core.fetcher)({
            url: core.url.join(
                (await core.Supplier.get(this._options.baseUrl)) ??
                    (await core.Supplier.get(this._options.environment)) ??
                    environments.IntercomEnvironment.UsProduction,
                "contacts",
            ),
            method: "GET",
            headers: _headers,
            queryParameters: requestOptions?.queryParams,
            timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 20) * 1000,
            maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
            abortSignal: requestOptions?.abortSignal,
            fetchFn: this._options?.fetch,
            logging: this._options.logging,
        });
        if (_response.ok) {
            return { data: _response.body as Intercom.unstable.ContactList, rawResponse: _response.rawResponse };
        }

        if (_response.error.reason === "status-code") {
            switch (_response.error.statusCode) {
                case 401:
                    throw new Intercom.unstable.UnauthorizedError(
                        _response.error.body as Intercom.unstable.Error_,
                        _response.rawResponse,
                    );
                default:
                    throw new errors.IntercomError({
                        statusCode: _response.error.statusCode,
                        body: _response.error.body,
                        rawResponse: _response.rawResponse,
                    });
            }
        }

        return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/contacts");
    }

    /**
     * You can create a new contact (ie. user or lead).
     *
     * @param {Intercom.CreateContactRequestTwo} request
     * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration.
     *
     * @throws {@link Intercom.unstable.UnauthorizedError}
     *
     * @example
     *     await client.unstable.contacts.createContact({
     *         "email": "joebloggs@intercom.io"
     *     })
     */
    public createContact(
        request?: Intercom.CreateContactRequestTwo,
        requestOptions?: ContactsClient.RequestOptions,
    ): core.HttpResponsePromise<Intercom.unstable.CreateContactResponse> {
        return core.HttpResponsePromise.fromPromise(this.__createContact(request, requestOptions));
    }

    private async __createContact(
        request?: Intercom.CreateContactRequestTwo,
        requestOptions?: ContactsClient.RequestOptions,
    ): Promise<core.WithRawResponse<Intercom.unstable.CreateContactResponse>> {
        const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest();
        const _headers: core.Fetcher.Args["headers"] = mergeHeaders(
            _authRequest.headers,
            this._options?.headers,
            mergeOnlyDefinedHeaders({ "Intercom-Version": requestOptions?.version }),
            requestOptions?.headers,
        );
        const _response = await (this._options.fetcher ?? core.fetcher)({
            url: core.url.join(
                (await core.Supplier.get(this._options.baseUrl)) ??
                    (await core.Supplier.get(this._options.environment)) ??
                    environments.IntercomEnvironment.UsProduction,
                "contacts",
            ),
            method: "POST",
            headers: _headers,
            contentType: "application/json",
            queryParameters: requestOptions?.queryParams,
            requestType: "json",
            body: request,
            timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 20) * 1000,
            maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
            abortSignal: requestOptions?.abortSignal,
            fetchFn: this._options?.fetch,
            logging: this._options.logging,
        });
        if (_response.ok) {
            return {
                data: _response.body as Intercom.unstable.CreateContactResponse,
                rawResponse: _response.rawResponse,
            };
        }

        if (_response.error.reason === "status-code") {
            switch (_response.error.statusCode) {
                case 401:
                    throw new Intercom.unstable.UnauthorizedError(
                        _response.error.body as Intercom.unstable.Error_,
                        _response.rawResponse,
                    );
                default:
                    throw new errors.IntercomError({
                        statusCode: _response.error.statusCode,
                        body: _response.error.body,
                        rawResponse: _response.rawResponse,
                    });
            }
        }

        return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/contacts");
    }

    /**
     * You can fetch the details of a single contact by external ID. Note that this endpoint only supports users and not leads.
     *
     * @param {Intercom.unstable.ShowContactByExternalIdRequest} request
     * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration.
     *
     * @throws {@link Intercom.unstable.UnauthorizedError}
     *
     * @example
     *     await client.unstable.contacts.showContactByExternalId({
     *         external_id: "cdd29344-5e0c-4ef0-ac56-f9ba2979bc27"
     *     })
     */
    public showContactByExternalId(
        request: Intercom.unstable.ShowContactByExternalIdRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): core.HttpResponsePromise<Intercom.unstable.ShowContactByExternalIdResponse> {
        return core.HttpResponsePromise.fromPromise(this.__showContactByExternalId(request, requestOptions));
    }

    private async __showContactByExternalId(
        request: Intercom.unstable.ShowContactByExternalIdRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): Promise<core.WithRawResponse<Intercom.unstable.ShowContactByExternalIdResponse>> {
        const { external_id: externalId } = request;
        const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest();
        const _headers: core.Fetcher.Args["headers"] = mergeHeaders(
            _authRequest.headers,
            this._options?.headers,
            mergeOnlyDefinedHeaders({ "Intercom-Version": requestOptions?.version }),
            requestOptions?.headers,
        );
        const _response = await (this._options.fetcher ?? core.fetcher)({
            url: core.url.join(
                (await core.Supplier.get(this._options.baseUrl)) ??
                    (await core.Supplier.get(this._options.environment)) ??
                    environments.IntercomEnvironment.UsProduction,
                `contacts/find_by_external_id/${core.url.encodePathParam(externalId)}`,
            ),
            method: "GET",
            headers: _headers,
            queryParameters: requestOptions?.queryParams,
            timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 20) * 1000,
            maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
            abortSignal: requestOptions?.abortSignal,
            fetchFn: this._options?.fetch,
            logging: this._options.logging,
        });
        if (_response.ok) {
            return {
                data: _response.body as Intercom.unstable.ShowContactByExternalIdResponse,
                rawResponse: _response.rawResponse,
            };
        }

        if (_response.error.reason === "status-code") {
            switch (_response.error.statusCode) {
                case 401:
                    throw new Intercom.unstable.UnauthorizedError(
                        _response.error.body as Intercom.unstable.Error_,
                        _response.rawResponse,
                    );
                default:
                    throw new errors.IntercomError({
                        statusCode: _response.error.statusCode,
                        body: _response.error.body,
                        rawResponse: _response.rawResponse,
                    });
            }
        }

        return handleNonStatusCodeError(
            _response.error,
            _response.rawResponse,
            "GET",
            "/contacts/find_by_external_id/{external_id}",
        );
    }

    /**
     * You can archive a single contact.
     *
     * @param {Intercom.unstable.ArchiveContactRequest} request
     * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration.
     *
     * @example
     *     await client.unstable.contacts.archiveContact({
     *         id: "63a07ddf05a32042dffac965"
     *     })
     */
    public archiveContact(
        request: Intercom.unstable.ArchiveContactRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): core.HttpResponsePromise<Intercom.unstable.ContactArchived> {
        return core.HttpResponsePromise.fromPromise(this.__archiveContact(request, requestOptions));
    }

    private async __archiveContact(
        request: Intercom.unstable.ArchiveContactRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): Promise<core.WithRawResponse<Intercom.unstable.ContactArchived>> {
        const { id } = request;
        const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest();
        const _headers: core.Fetcher.Args["headers"] = mergeHeaders(
            _authRequest.headers,
            this._options?.headers,
            mergeOnlyDefinedHeaders({ "Intercom-Version": requestOptions?.version }),
            requestOptions?.headers,
        );
        const _response = await (this._options.fetcher ?? core.fetcher)({
            url: core.url.join(
                (await core.Supplier.get(this._options.baseUrl)) ??
                    (await core.Supplier.get(this._options.environment)) ??
                    environments.IntercomEnvironment.UsProduction,
                `contacts/${core.url.encodePathParam(id)}/archive`,
            ),
            method: "POST",
            headers: _headers,
            queryParameters: requestOptions?.queryParams,
            timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 20) * 1000,
            maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
            abortSignal: requestOptions?.abortSignal,
            fetchFn: this._options?.fetch,
            logging: this._options.logging,
        });
        if (_response.ok) {
            return { data: _response.body as Intercom.unstable.ContactArchived, rawResponse: _response.rawResponse };
        }

        if (_response.error.reason === "status-code") {
            throw new errors.IntercomError({
                statusCode: _response.error.statusCode,
                body: _response.error.body,
                rawResponse: _response.rawResponse,
            });
        }

        return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/contacts/{id}/archive");
    }

    /**
     * You can unarchive a single contact.
     *
     * @param {Intercom.unstable.UnarchiveContactRequest} request
     * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration.
     *
     * @example
     *     await client.unstable.contacts.unarchiveContact({
     *         id: "63a07ddf05a32042dffac965"
     *     })
     */
    public unarchiveContact(
        request: Intercom.unstable.UnarchiveContactRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): core.HttpResponsePromise<Intercom.unstable.ContactUnarchived> {
        return core.HttpResponsePromise.fromPromise(this.__unarchiveContact(request, requestOptions));
    }

    private async __unarchiveContact(
        request: Intercom.unstable.UnarchiveContactRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): Promise<core.WithRawResponse<Intercom.unstable.ContactUnarchived>> {
        const { id } = request;
        const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest();
        const _headers: core.Fetcher.Args["headers"] = mergeHeaders(
            _authRequest.headers,
            this._options?.headers,
            mergeOnlyDefinedHeaders({ "Intercom-Version": requestOptions?.version }),
            requestOptions?.headers,
        );
        const _response = await (this._options.fetcher ?? core.fetcher)({
            url: core.url.join(
                (await core.Supplier.get(this._options.baseUrl)) ??
                    (await core.Supplier.get(this._options.environment)) ??
                    environments.IntercomEnvironment.UsProduction,
                `contacts/${core.url.encodePathParam(id)}/unarchive`,
            ),
            method: "POST",
            headers: _headers,
            queryParameters: requestOptions?.queryParams,
            timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 20) * 1000,
            maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
            abortSignal: requestOptions?.abortSignal,
            fetchFn: this._options?.fetch,
            logging: this._options.logging,
        });
        if (_response.ok) {
            return { data: _response.body as Intercom.unstable.ContactUnarchived, rawResponse: _response.rawResponse };
        }

        if (_response.error.reason === "status-code") {
            throw new errors.IntercomError({
                statusCode: _response.error.statusCode,
                body: _response.error.body,
                rawResponse: _response.rawResponse,
            });
        }

        return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/contacts/{id}/unarchive");
    }

    /**
     * Block a single contact.<br>**Note:** conversations of the contact will also be archived during the process.<br>More details in [FAQ How do I block Inbox spam?](https://www.intercom.com/help/en/articles/8838656-inbox-faqs)
     *
     * @param {Intercom.unstable.BlockContactRequest} request
     * @param {ContactsClient.RequestOptions} requestOptions - Request-specific configuration.
     *
     * @example
     *     await client.unstable.contacts.blockContact({
     *         id: "63a07ddf05a32042dffac965"
     *     })
     */
    public blockContact(
        request: Intercom.unstable.BlockContactRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): core.HttpResponsePromise<Intercom.unstable.ContactBlocked> {
        return core.HttpResponsePromise.fromPromise(this.__blockContact(request, requestOptions));
    }

    private async __blockContact(
        request: Intercom.unstable.BlockContactRequest,
        requestOptions?: ContactsClient.RequestOptions,
    ): Promise<core.WithRawResponse<Intercom.unstable.ContactBlocked>> {
        const { id } = request;
        const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest();
        const _headers: core.Fetcher.Args["headers"] = mergeHeaders(
            _authRequest.headers,
            this._options?.headers,
            mergeOnlyDefinedHeaders({ "Intercom-Version": requestOptions?.version }),
            requestOptions?.headers,
        );
        const _response = await (this._options.fetcher ?? core.fetcher)({
            url: core.url.join(
                (await core.Supplier.get(this._options.baseUrl)) ??
                    (await core.Supplier.get(this._options.environment)) ??
                    environments.IntercomEnvironment.UsProduction,
                `contacts/${core.url.encodePathParam(id)}/block`,
            ),
            method: "POST",
            headers: _headers,
            queryParameters: requestOptions?.queryParams,
            timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 20) * 1000,
            maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
            abortSignal: requestOptions?.abortSignal,
            fetchFn: this._options?.fetch,
            logging: this._options.logging,
        });
        if (_response.ok) {
            return { data: _response.body as Intercom.unstable.ContactBlocked, rawResponse: _response.rawResponse };
        }

        if (_response.error.reason === "status-code") {
            throw new errors.IntercomError({
                statusCode: _response.error.statusCode,
                body: _response.error.body,
                rawResponse: _response.rawResponse,
            });
        }

        return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/contacts/{id}/block");
    }
}
